C++構造函數調用順序
-
創建派生類的對象,基類的構造函數優先被調用(也優先於派生類里的成員類);
-
如果類里面有成員類,成員類的構造函數優先被調用;(也優先於該類本身的構造函數)
-
基類構造函數如果有多個基類,則構造函數的調用順序是某類在類派生表中出現的順序而不是它們在成員初始化表中的順序;
-
成員類對象構造函數如果有多個成員類對象,則構造函數的調用順序是對象在類中被聲明的順序而不是它們出現在成員初始化表中的順序;
-
派生類構造函數,作為一般規則派生類構造函數應該不能直接向一個基類數據成員賦值而是把值傳遞給適當的基類構造函數,否則兩個類的實現變成緊耦合的(tightly coupled)將更加難於正確地修改或擴展基類的實現。(基類設計者的責任是提供一組適當的基類構造函數)
綜上可以得出,初始化順序:
父類構造函數–>成員類對象構造函數–>自身構造函數
其中成員變量的初始化與聲明順序有關,構造函數的調用順序是類派生列表中的順序。
析構順序和構造順序相反
示例
class A
{
public:
A(){ cout<<"A"<<endl;}
virtual ~A(){ cout<<"~A"<<endl; }
};
class B: public A
{
public:
B(){ cout<<"B"<<endl;}
~B() {cout<<"~B"<<endl; }
private:
A a;
};
class C: public A, public B //類在派生表中的繼承列表
{
public:
C() {cout<<"C"<<endl;}
~C() {cout<<"~C"<<endl; }
private:
B b;
public:
A a;
};
int main()
{
C * p = new C;
delete p;
system("PAUSE");
return 0;
}
結果:
A //1 父類A的構造函數
A //2 父類B中A的構造函數
A //3 父類B中成員變量b初始化 (調用父類A的構造函數)
B //4 父類B中成員變量b初始化 (調用父類B的構造函數)
A //5 C中成員變量b的構造
A
B
A //6 C中成員變量a的構造
C //7 C的構造函數最后調用
~C
~A
~B
~A
~A
~B
~A
~A
~A