構造函數和變量初始化順序

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()。

 

總結:初始化一個類對象的時候,首先構造這個類的基類,接着初始化這個類的成員變量,最後調用構造函數。自然,析構的順序和構造次序相反。

發佈了15 篇原創文章 · 獲贊 1 · 訪問量 24萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章