继承
(1).目的:为了代码的复用、允许在保持原有类特性的基础上进行扩展 、增加功能
(2).继承关系&访问限定符:
public、protected、private
(3).派生类的六个成员函数
构造函数、析构、拷贝构造、赋值运算符重载、取地址符操作符重载、const修饰的取地址操作符重载
继承过程中构造函数调用顺序:基类构造函数——>派生类中对象构造函数——>派生类构造函数体 class A { public: A() :a(1) { cout<<"A()"<<endl; cout<<a<<endl; } void fun() { cout<<"A-fun()"<<endl; } ~A() { cout<<"~A()"<<endl; } private: int a; }; class B:public A { public: B() { cout<<"B()"<<endl; } void fun() { cout<<"B-fun1()"<<endl; } ~B() { cout<<"~B()"<<endl; } private: int b; }; int main() { A a; B b; return 0; }
(4).赋值兼容规则
a.子类对象可以赋值给父类对象(切割/切片)
b.父类对象不能赋值给子类对象
c.父类的指针/引用可以指向子类对象
d.子类的指针或者对象不能指向父类对象(可以强制类型转换)
(5).单继承&多继承&菱形继承
单继承:一个子类只有一个直接父类的继承关系
多继承:一个子类有两个或以上的直接父类的继承关系
菱形继承:存在二义性和数据冗余问题
class A { public: int a; private: int a1; }; class B:public A { public: int b; private: int b1; }; class C:public A { public: int c; private: int c1; }; class D:public B,public C { public: int d; private: int d1; }; int main() { cout<<sizeof(A)<<endl;//8 cout<<sizeof(B)<<endl;//16 cout<<sizeof(C)<<endl;//16 cout<<sizeof(D)<<endl;//40 将a a1保存了两份 D d; d.a=3; //产生对a访问的二义性 d.C::a / d.B::a return 0; } ***虚承继的情况:由于涉及到虚函数表和虚基表,会同时增加一个(多重虚继承下对应多个)vfPtr指针指向虚函数表vfTable和一个vbPtr指针指向虚基表vbTable,这两者所占的空间大小为:8(或8乘以多继承时父类的个数);
用虚继承解决菱形继承的二义性和数据冗余问题