你好你好!
以下内容仅为当前认识,可能有不足之处,欢迎讨论!
文章目录
继承
继承语法
目的:减少代码复用
语法:在类后面写一个class 子类 : 继承方式 父类
,就算继承了。
案例:
#include<iostream>
#include<string>
using namespace std;
class BasePage {
public:
void header() {
cout << "==========网页头部==========" << endl;
}
void footer() {
cout << "**********网页尾部**********" << endl;
}
};
class PythonPage :public BasePage {
public:
PythonPage() {
python();
}
void python() {
BasePage().header();
cout << "~~~~~~~~~~python网页~~~~~~~~~~" << endl;
BasePage().footer();
}
};
class CPPPage :public BasePage {
public:
CPPPage() {
CPP();
}
void CPP() {
BasePage().header();
cout << "~~~~~~~~~~CPP网页~~~~~~~~~~" << endl;
BasePage().footer();
}
};
class JavaPage :public BasePage {
public:
JavaPage() {
Java();
}
void Java() {
BasePage().header();
cout << "~~~~~~~~~~Java网页~~~~~~~~~~" << endl;
BasePage().footer();
}
};
void test_0217_0() {
PythonPage python_page;
CPPPage cpp;
JavaPage java;
}
int main() {
cout << "hello ! world ! " << endl;
test_0217_0();
system("pause");
return 0;
}
运行结果:
此处有疑惑,继承的父类不能有构造函数?
继承方式
公有继承:父类里面成员属性是什么权限,之后仍然是什么权限。
保护权限:父类里面的public
&protected
变为子类的protected
权限。
私有继承:父类里面的public
&protected
变为子类的private
权限。
父类的private
权限内容,其他都无法访问。
代码说明:
①公有权限
class BaseClass {
public:
int class_a;
protected:
int class_b;
private:
int class_c;
};
class PublicSon :public BaseClass {
PublicSon() {
class_a = 100;
class_b = 200;
//class_c = 300;
}
};
根据图可以看出,在继承方式为public
时,无法访问父类中private
权限下的内容,只能访问权限为public
和protected
下的内容。此时,父类与子类的权限变化如下表格
继承方式为public 权限/类 |
父类 | 子类 |
---|---|---|
继承方式为public 权限 |
public | public |
继承方式为public 权限 |
protected | protected |
继承方式为public 权限 |
private | 无法访问 |
②保护权限
继承方式为protected时,代码:
class BaseClass {
public:
int class_a;
protected:
int class_b;
private:
int class_c;
};
class ProtectedSon :protected BaseClass {
ProtectedSon() {
class_a = 100;
class_b = 200;
//class_c = 300;
}
};
此时,父类为private
权限下的内容仍然无法访问。
权限变化如下表格:
继承方式为protected 权限/类 |
父类 | 子类 |
---|---|---|
继承方式为protected 权限 |
public | protected |
继承方式为protected 权限 |
protected | protected |
继承方式为protected 权限 |
private | 无法访问 |
③私有权限
私有权限将父类中的所有成员属性在子类继承时转换为了private
权限,在孙类继承时无法获得子类成员属性。
class BaseClass {
public:
int class_a;
protected:
int class_b;
private:
int class_c;
};
class PrivateSon :private BaseClass {
PrivateSon() {
class_a = 100;
class_b = 200;
}
};
class GrandSon :public PrivateSon {
void print() {
cout << "class_a = " << class_a << endl;
cout << "class_c = " << class_b << endl;
}
};
如图所示:
可以看到无法访问class_a
的值。
继承中的对象模型
问题:
子类对于父类中的成员是都继承吗?
回答:
对于非静态成员变量,都继承。
验证:
解决办法:①在程序中打印出所占内存大小;②利用开发人员命令提示工具查看对象模型。
①代码
#include<iostream>
using namespace std;
#include<string>
class BaseClass {
public:
int class_a;
protected:
int class_b;
private:
int class_c;
};
class SonClass : public BaseClass {
public:
int class_d;
};
void test_0218_0() {
cout << "the SonClass size = " << sizeof(SonClass) << "." << endl;
}
int main() {
cout << "hello ! world ! " << endl;
test_0218_0();
system("pause");
return 0;
}
运行结果:
可以看到,只是编译器以及协议说明父类的私有权限下的内容无法访问,但是子类仍然有其成员属性。
②利用开发人员命令提示工具查看对象模型(开始菜单中)
进入当前文件所在文件夹后,用cl /d1 reportSingleClassLayout类名 "文件名"
查看当前类的排列信息。
可以看到SonClass占16字节,因为有4个整型构成。
同样,查看BaseClass。
最后结论:父类中私有成员也被子类继承,只是由编译器隐藏后无法访问。
继承中构造和析构顺序
在父类和子类初始化时,它们的构造顺序和析构顺序是怎样的?
代码验证:
#include<iostream>
using namespace std;
#include<string>
class BaseClass {
public:
BaseClass() {
cout << "==父类==构造==函数==" << endl;
}
~BaseClass() {
cout << "==父类==析构==函数==" << endl;
}
public:
int class_a;
protected:
int class_b;
private:
int class_c;
};
class SonClass : public BaseClass {
public:
SonClass() {
cout << "==子类==构造==函数==" << endl;
}
~SonClass() {
cout << "==子类==析构==函数==" << endl;
}
public:
int class_d;
};
void test_0218_0() {
SonClass sc;
cout << "the SonClass size = " << sizeof(SonClass) << "." << endl;
}
int main() {
cout << "hello ! world ! " << endl;
test_0218_0();
system("pause");
return 0;
}
运行结果
由运行结果可以看出,是父类先构造,子类再构造,而释放时,是由子类先释放,父类后释放。
同名成员处理
问题:父类和子类若有同名的成员属性和成员函数,如何分别访问?有何区别?
结论:子类继承父类后,新建子类对象,会访问到子类成员属性和成员函数。如需访问父类成员属性或成员函数,需加作用域。
延申提问:①重名但是不重类型的成员属性,是否会冲突?②重名成员函数若在父类中重载,重载为有参的成员函数,是否能访问到父类成员函数?
对应结论:①②不可以,发生重名成员函数,即编译器隐藏掉父类所有对应成员函数,除非加上作用域访问。
成员属性&成员函数举例:
#include<iostream>
#include<string>
using namespace std;
class BaseClass {
public:
BaseClass() {
class_a = 100;
}
int class_a;
void print() {
cout << "Base Class print() function 调用." << endl;
}
//void print(int a):class_a(a) {//这个只有在构造函数成员函数初始化时才能用
void print(int a ){
cout << "Base Class print ( int a ) function 调用." << endl;
}
};
class SonClass:public BaseClass {
public:
SonClass() {
class_a = 200;
}
int class_a;
void