C++構造及析構執行順序

在C++中,當創建一個類對象時,編譯器是會自動調用一個叫構造函數的東西的,我們知道,C++類與類之間很多情況下是有關聯的,比如繼承,組合等等。本文主要通過實例總結各種情況下的構造與析構順序。

繼承

場景:B類繼承兩個父類A和C,每個類的構造函數和析構函數很簡單,就是打印對應的函數名,以便觀察構造及析構函數執行順序。

#include using namespace std;class A{ public: A(){cout << “A()” << endl;} ~A(){cout << “~A()” << endl;}};class C{ public: C(){cout << “C()” << endl;} ~C(){cout << “~C()” << endl;}};class B: public A, public C{ public: B(){cout << “B()” << endl;} ~B(){cout << “~B()” << endl;}};int main(int argc, char const *argv[]){ B b; return 0;}

bogon:dataStructure lizhong$ ./tA()C()B()B()C()~A()

通過運行結果可以看出:創造一個子類對象時,先執行父類的構造函數,再執行自身的構造函數,如果子類繼承多個父類,則按照繼承的順序從左到右調用父類構造函數(本例先構造A,再構造C),析構的順序與構造的順序相反。

我們還知道還有一種繼承叫做虛擬繼承,看看這種情況下的構造與析構又是怎樣的順序。

#include using namespace std;class A{ public: A(){cout << “A()” << endl;} ~A(){cout << “~A()” << endl;}};class C{ public: C(){cout << “C()” << endl;} ~C(){cout << “~C()” << endl;}};class B: public A, public C{ public: B(){cout << “B()” << endl;} ~B(){cout << “~B()” << endl;}};int main(int argc, char const *argv[]){ B b; return 0;}

bogon:dataStructure lizhong$ ./tC()A()B()B()A()~C()

可以看出:虛擬繼承和一般的繼承構造和析構的順序還是有點不一樣,父類的構造順序發生了改變,虛擬繼承的C構造函數先被執行,然後是A。最後是自身的構造函數被調用,析構的順序與構造的順序相反。

成員包含其它類對象成員

場景:B類含有A類對象和C類對象的成員,且在B類中,其成員聲明順序是先聲明c,再聲明a。看看創造B類對象時,構造函數和析構函數的執行順序是怎樣的。

#include using namespace std;class A{ public: A(){cout << “A()” << endl;} ~A(){cout << “~A()” << endl;}};class C{ public: C(){cout << “C()” << endl;} ~C(){cout << “~C()” << endl;}};class B{ public: B():a(A()), c(C()) {cout << “B()” << endl;} ~B(){cout << “~B()” << endl;} C c; A a;};int main(int argc, char const *argv[]){ B b; return 0;}

bogon:dataStructure lizhong$ ./tC()A()B()B()A()~C()

運行結果可以看出:創造一個B類對象b時,先執行其成員對象所屬類的構造函數,再執行自身的構造函數,如果有多個類對象成員,則按照聲明的順序調用對應類的構造函數(本例先構造C類對象c,再構造A類對象a),析構的順序與構造的順序相反。

即有繼承又包含類對象成員

場景:B類繼承兩個父類A和C,並且B類有一個X類的對象成員,觀察構造及析構函數執行順序。

#include using namespace std;class A{ public: A(){cout << “A()” << endl;} ~A(){cout << “~A()” << endl;}};class C{ public: C(){cout << “C()” << endl;} ~C(){cout << “~C()” << endl;}};class X{ public: X(){cout << “X()” << endl;} ~X(){cout << “~X()” << endl;}};class B: public A, public C{ public: B(){cout << “B()” << endl;} ~B(){cout << “~B()” << endl;} X x;};int main(int argc, char const *argv[]){

B b;

return 0;}

bogon:dataStructure lizhong$ ./tA()C()X()B()B()X()C()A()

運行結果可以看出:類在構造的時候會先從左到右調用父類的構造函數,然後調用類對象成員構造函數,最後調用自身構造函數。析構的順序與構造的順序相反。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章