目录
3-11 基类与派生类关系的详细再探讨
派生类对象模型简述:派生类有多个部分组成
1、一个是含有派生类自己定义的成员变量,成员函数的子对象。
2、一个是派生类继承的基类的子对象,因为派生类含有基类部分,所以我们可以把派生类对象当成基类对象来用(派生类成员与基类成员不一定存放在同一块连续的内存中)。
基类指针可以new派生类对象,是因为派生类对象含有基类部分,所以我们可以把派生类对象当成基类对象用。
这里编译器帮助我们做了一个隐式转换。这种转换的好处就是,有些需要用基类引用的地方你可以使用派生类对象的引用来代替,有些需要基类指针的地方也可以用派生类对象指针来代替。
二、派生类构造函数:
派生类实际时使用基类的构造函数来初始化基类部分。基类控制基类部分成员的初始化,派生类控制派生类部分成员的初始化。
传递参数给基类构造函数:通过派生类的构造函数初始化列表
class A{
public:
A(int i):value(i){};
private:
int value;
};
class B : public A{
public:
B(int i, int j, int k):m_value(j), A(i) {};
int m_valueB;
};
构造函数:先执行基类的构造函数,在执行派生类的构造函数
释放时:限制性派生类的析构函数,在执行基类的析构函数
三、既当父类又当子类
C++的继承会一直传递,A->B->C,最终结果就是C会包含他的直接基类成员,以及每个间接基类的成员。
四、不想当基类的类
如果某个类不想被继承,那么可以在类名后加final c++11
class A final{
public:
A(int i):value(i){};
private:
int value;
};
五、静态类型与动态类型
静态类型指的是编译的时候已知。
动态类型:值得时这个指针/引用所代表的内存中的对象类型,动态类型时运行的时候才知道。
动态类型这种概念,只有基类指针/引用 才存在这种静态类型和动态类型不一致的情况。
如果不是基类指针/引用,那么静态类型和动态类型永远都是一致的。
六、派生类向基类的隐式类型转换:
Human *phuman = new Man(); //基类
Human &q = *phuman; //基类引用绑定到派生类对象上
之所以能够转换成功是因为每个派生类,都包含基类对象部分,所以基类的引用或指针可以绑定到派生类对象的基类部分。
基类对象能够独立存在,也能作为派生类对象的一部分的存在。
但是并不存在从基类到派生类的转换
派生类的引用不能绑定到基类对象上。
编译器通过静态类型判断转换的合法性。
Men men;
Human *phuman = &men;
Men *pmen = phuman; //不可以,编译器通过静态类型判断转换的合法性,发现基类不能转换成派生类
dynamic_cast<>可以
七、父类与子类之间的拷贝与赋值
Men men;
Human human(men);//派生类对象来定义并初始化基类对象,这个会导致基类的拷贝构造函数的执行
派生类对象给基类初始化,基类对象只能得到相应基类的成员初始化。派生类部分将被忽略掉
也就是基类只干自己的事情。
派生类向基类的自动类型转换
c++ 派生类向基类转换的可访问性