二义性、多态、纯虚函数、模板函数
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;
}