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

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

#include <iostream>
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构造函数初始化
	}

;

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;
}

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;
}


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;
}

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){}
];

6、回调

#include <iostream>
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;
}

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;
]

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值