派生类的默认成员函数
a.派生类的构造函数必须调用基类的构造函数初始化基类的那一部分成员,如果基类没有默认的构造函数,则必须在派生类构造函数的初始化列表阶段显示调用。
b.派生类的拷贝构造函数必须调用基类的拷贝构造完成基类的拷贝初始化。
c.派生类的operator=必须要调用基类的operator=完成基类的复制。
d.派生类的析构函数会在被调用完成后自动调用基类的析构函数清理基类成员,因为这样才能保证派生类对象先清理派生类成员再清理基类成员的顺序。
e.派生类对象初始化先调用基类构造再调派生类构造。
f.派生类对象析构清理先调用派生类析构再调用基类析构。
构造一个子类时,完成其基类部分的构造由基类的构造函数去做、
派生类的构造总是由基类的初始化开始
继承方式
从上图可以看出:
当public继承的时候,父类中public类型的成员会被继承到子类的public中去,而父类的protected成员也会被继承到子类的protected中去
当protected继承的时候,父类中无论是public的还是protected的成员都会被继承到子类的protected中去
当private继承的时候,父类中 public 和 protected 的成员都会被继承到子类的private中去
注意:父类的private成员是无论如何都不能被继承的。
即,一个保护或私有的派生类不是子类
私有继承派生类可以通过自身成员函数访问父类保护和公有成员,但不能直接访问基类私有成员,必须通过保护成员或公有的基类函数成员去访问基类的私有成员
多继承的构造顺序
//---------------------
#include<iostream>
using namespace std;
//---------------------
class OBJ1{
public:
OBJ1(){ cout<<"OBJ1\n"; }
};//-------------------
class OBJ2{
public:
OBJ2(){ cout<<"OBJ2\n"; }
};//-------------------
class B1{
public:
B1(){ cout<<"Base1\n"; }
};//-------------------
class B2{
public:
B2(){ cout<<"Base2\n"; }
};//-------------------
class B3{
public:
B3(){ cout<<"Base3\n"; }
};//-------------------
class B4{
public:
B4(){ cout<<"Base4\n"; }
};//-------------------
class Derived:public B1,virtual public B2,public B3,virtual public B4{
public:
Derived():B4(),B3(),B2(),B1(),obj2(),obj1(){
cout<<"Derived ok.\n";
}
protected:
OBJ1 obj1;
OBJ2 obj2;
};//-------------------
int main(){
Derived aa;
cout<<"This is ok.\n";
}//--------------------
Base2
Base4
Base1
Base3
OBJ1
OBJ2
Derived ok.
This is ok.
- 任何虚拟基类的构造函数按照他们被继承的顺序
- 任何非虚拟基类的构造函数按照他们被继承的顺序构造
- 任何成员对象的构造函数按照他们声明的顺序调用
- 类自己的构造函数
另附一篇文的链接