class A
{
public:
A(){ cout<<"A()"<<endl;}
~A(){ cout<<"~A()"<<endl;}
};
class B
{
public:
B(){ cout<<"B()"<<endl; }
~B(){ cout<<"~B()"<<endl; }
private:
A a;
};
class C :public B
{
public:
C(){ cout<<"C()"<<endl;}
~C(){cout<<"~C()"<<endl;}
private:
B b;
A a;
};
int _tmain(int argc, _TCHAR* argv[])
{
C* p = new C;
delete p;
return 0;
}
輸出:
A() //這一行和下一行是爲了構造C類對象的基類B,而在構造基類B的時候需要先初始化B的成員變量a,因而調用了A的構造函數
B()
A() //這一行和下一行是C類對象在初始化成員變量b時,需要構造B,因此需要先初始化B的成員變量a,因而再次調用了A的構造函數
B()
A() //這一行是C類對象初始化成員變量a是,需要構造A
C() //構造完畢C類對象的基類B和自身成員變量a,b之後,調用自己的構造函數
~C() //析構次序和構造次序相反
~A()
~B()
~A()
~B()
~A()
大家可以驗證做一些測試,比如把B改爲
class B
{
public:
B(){ cout<<"B()"<<endl; }
~B(){ cout<<"~B()"<<endl; }
};
這樣輸出結果:
B()
B()
A()
C()
~C()
~A()
~B()
~B()
看到了吧,這樣C在構造基類對象B和初始化成員變量b的時候就不用再構造A,因此就去掉了A()。
總結:初始化一個類對象的時候,首先構造這個類的基類,接着初始化這個類的成員變量,最後調用構造函數。自然,析構的順序和構造次序相反。