• C++二义性、多态、纯虚函数、模板函数


    1、源码中属性初始化的方式

    #include 
    using namespace std;
    
    //人类
    class Person{
    private:
    	//注意: string 是std 命名空间里面的,C++源码:std::string
    	// String 内部其实就是对 char * 的封装
    	String name;
    	int age;
    public:
    	Person(string name, int age):name(name),age(age){}
    };
    //课程类
    class Course{
    private:
    	string name;
    public:
    	Course(string name):name(name){}
    }; 
    class Student : public Person{}
    private:
    	//如果定义的是是对象成员,必须这样初始化:构造函数的后面:对象成员(内容)
    	Course course;//对象成员
    public:
    	Student(string name, int age, Course course, string courseNmaeInfo):
    	Person(name,age), course(course){// 既然继承了父类就必须给父类的构造函数初始化
    		//this->course = course; 编译器不认可,无法检测到你是否给course初始化了
    		//所以用, course(course)的方式 直接给成员变量course赋值
    		//还有一种, course(courseNameInfo) 会直接调用course构造函数初始化
    	}
    
    ;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    2、虚继承、二义性

    class Object{
    public: string info;
    	void show(){
    	cout << "object show run... " << endl;}
    };
    
    //父类1
    class Base1 : virtual public Object{
    };
    //父类2
    class Base2: virtual public Object{
    };
    //子类
    class Son : public Base1, public Base2{
    };
    
    int main(){
    	Object object1;//在栈区开辟,就会有一个this的指针,假如指针是1000H,会有指向能力
    	Base1 base1;//在栈区开辟,就会有一个this的指针,假如指针是2000H,会有指向能力
    	Base2 base2;//在栈区开辟,就会有一个this的指针,假如指针是3000H,会有指向能力
    	Son son;//在栈区开辟,就会有一个this的指针,假如指针是4000H,会有指向能力
    	object.info = "a";
    	base1.info = "b";
    	base2.info = "c";
    	son.info = "d";
    	cout << object.info << endl;
    	cout << base1.info << endl;
    	cout << base2.info << endl;
    	cout << son.info << endl;
    	// 输出 a b c d
    	//info 只有一份,可以理解它有四个别名地址,指向同一个info在栈内存,
    	//字符串常量区是有a、b、c、d四个,实际流程必须要看汇编代码才能更清晰
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    3、多态(虚函数)

    // android 标准
    class BaseActivity{
    public:
    	void onStart(){
    	cout << "BaseActivity onStart" << endl;
    	}
    };
    
    class HomeActivity : public BaseActivity{
    public:
    	void onStart(){ //重写父类的函数
    	cout << "HomeActivity onStart" << endl;
    	}
    };
    
    class LoginActivity : public BaseActivity{
    public:
    	void onStart(){ //重写父类的函数
    	cout << "LoginActivity onStart" << endl;
    	}
    };
    
    // 在此喊你书提现多态,你传入HomeActivity,我就帮你运行HomeActiivty
    void startToActivity(BaseActivity * baseActivity){
    	baseActivity->onStart();
    }
    
    // 重载 静态多态
    void add(int number1, int number2){
    	cout << number1 + number2 << endl;
    }
    
    void add(float number1, float number2){
    	cout << number1 + number2 << endl;
    }
    
    void add(double number1, double number2){
    	cout << number1 + number2 << endl;
    }
    
    
    
    
    
    int mian(){
    	// 第一版
    	HomeActivity * homeActivity = new HomeActivity();
    	LoginActivity * loginActivity = new LoginActivity();
    	startToActivity(homeActivity);
    	startToActivity(loginActivity);
    	if(homeActivity && loginActivity) {
    		delete homeActivity;
    		delete loginActivity;
    	}
    	//打印的都是BaseActivity的onStart,跟java不同
    	//java默认支持多态,C++ 默认关闭多态,怎么开启?
    	// 第二版
    	BaseActivity * homeActivity = new HomeActivity();
    	BaseActivity * loginActivity = new LoginActivity();
    	startToActivity(homeActivity);
    	startToActivity(loginActivity);
    	if(homeActivity && loginActivity) {
    		delete homeActivity;
    		delete loginActivity;
    	}
    	//打印的都是BaseActivity的onStart
    	//开启,在父类上给函数增加virtual关键字 ,动态多态
    	public:
    		virtual	void onStart(){
    	cout << "HomeActivity onStart" << endl;
    	}
    	// 什么是多态? 父类的引用指向子类的引用 同一个方法有不同的实现,重写和重载
    	//从程序上,在运行期间才能知道是哪个具体类的函数 == 动态多态
    	// 重载 静态多态,编译器就知道了
    	add(1,1);
    	add(1.0f,2.0f);
    	add(1.2,1.22);
    	return 0;
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81

    4、纯虚函数(java版抽象类)

    #inlcude <iostream>
    using namespace std;
    
    // C++没有抽象类,纯虚函数相当于java的抽象类
    class BaseActivity{
    private:
    	void setContextView(String layoutResId){
    	cout << "xmlResourParser解析布局文件信息...反射" << endl;
    	}
    public:
    	//1、普通函数
    	void onCreate(){
    	setContextView(getLayoutId());
    		initView();
    		initData();
    		initListener();
    	}
    	//2/抽象函数/纯虚函数
    	//virtual string getLayoutID();//虚函数
    	virtual string getLayoutID() = 0;//纯虚函数
    	virtual void initView() = 0;
    	virtual void initData() = 0;
    	virtual void initListener() = 0;
    };
    
    // 子类 MainActivity,要不重写父类的纯虚函数,自己就相当于抽象类了
    class MainActivity : public BaseActivity{
    	//没实现父类的纯虚函数,报错了,下面实现一下。
    	string getLayoutID(){
    		return "R.layout.activity_main" ;
    	}
    	void initView(){]
    	void initData(){]
    	void initListener(){]
    };
    
    
    int mian(){
    	//抽象类型不能实例化,报错,必须实现父类的纯虚函数
    	MainActivity mianActivity;
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    5、全纯虚函数(java版接口)

    C++是没有接口的,只是在比喻

    
    class Student{
    	int _id;
    	string name;
    	int age;
    };
    
    //此类所有的函数都是纯虚函数,相当于java的接口了。
    class ISudent_DB{
    	virtual void insertStuendt(Student student) = 0;
    	virtual void deleteStuendt(int _id) = 0;
    	virtual void updateStuendt(int _id, Student student) = 0;
    	virtual void queryStuendt(Student student) = 0;
    };
    
    //java的实现类
    class Student_DBImpl : public ISudent_DB{
    	void insertStudent(Student student){}
    	void deleteStuendt(int _id){}
    	void updateStuendt(int _id, Student student){}
    	void queryStuendt(Student student){}
    ];
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    6、回调

    #include 
    using namespace std;
    
    //登录成功的Bean
    class SuccessBean{
    public:
    	string username;
    	string userpwd;
    	SuccessBean(string username, string userpwd)
    	: username(username),userpwd(userpwd){}
    };
    //登录的接口 成功、错误
    class ILoginResponse{
    public:
    	//成功
    	virtual void loginSuccess(int code, string message, SuccessBean successBean) = 0;
    	//失败
    	virtual void loginError(int code, string message) = 0;
    };
    // 登录的API操作
    void loginAction(string name, string pwd, IloginResponse & loginResponse){
    	if(name.empty() || pwd.empty()) {
    		cout << "用户或密码为空!" << endl;
    		return;
    	}
    	if("abce" == name && "123456" == pwd) {
    		loginResPonse.loginSuccess(200, "登录成功", SuccessBean(name,""恭喜你进入));
    	} else {
    		loginResponse.loginError(404,"错误,用户名或者密码错误...")}
    }
    // 写一个实现类
    class ILoginRespinseImpl : public ILoginResponse{
    public:
    	//成功
    	void loginSuccess(int code, string message, SuccessBean successBean){}
    	//失败
    	void loginError(int code, string message){}
    };
    int mian(){
    /** 报错:正在分配抽象类型为ILoginResponse的对象,不能被实例化 
    	加new是在堆,没有new是在栈,都是实例化
    	纯虚函数不准你实例化
    	new ILoginResponse(){
    		void loginSuccess(int code, string message, SuccessBean successBean){}
    		void loginError(int code, string message){}
    	}
    */
    	string username;
    	cout << "请输入用户名" << endl;
    	cin >> usernmae; 
    	string userpwd;
    	cout << "请输入密码" << endl;
    	cin >> userpwd;
    	ILoginResponseImpl iLoginResponse;
    	loginAction(username,userpwd, iLoginResponse);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    7、模板函数(java版泛型)

    //加分合集 int double float,要定义很多的函数? 其它函数我就不多写了
    void addAction(int n1, int n2){
    	cout << n1 + n2 << endl;
    }
    
    // 模板函数 == java的泛型解决此问题
    template <typename TT>
    void addAction1(TT n1, TT n2){
    cout << n1 + n2 << endl;
    }
    
    int main(){
    	addAction1(1,2);
    	addAction1(1.0,2.0);
    	return 0;
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    8、继承中构造函数和析构函数的顺序问题

    class Person{
    public:
    	string name;
    	Person(string name): name(name{cout << "Person构造函数" << endl;})
    	~Person():{cout << "Person析构函数" << endl;})
    };
    
    class Student : public Person{
    public:
    	string name;
    	Student(string name) : Person(name) {
    	cout << "Student构造函数" << endl;
    	}
    	~Student():{cout << "Student析构函数" << endl;})
    };
    int main(){
    	Student student("abde");
    	//顺序 父类先构造函数执行再子类
    	// 释放:子类先释放在执行父类
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
  • 相关阅读:
    原生小程序一键获取手机号
    2023年全国职业院校技能大赛(高职组)“云计算应用”赛项赛卷9(私有云)
    Revel框架基本使用和搭建教程
    NodeMCU ESP8266基于Arduino IDE的开发环境搭建(图文并茂)
    循环购商业模式:实现用户裂变的关键
    PHP通过sql生成CSV文件并下载,PHP实现文件下载
    springcloude gateway的意义
    8 ActiveMQ的持久化
    Xpath的使用
    web-traffic-generator:一款功能强大的HTTP和HTTPs流量混淆工具
  • 原文地址:https://blog.csdn.net/qq_34606099/article/details/126164519