构造函数和析构函数的调用过程
B、~B ~A
C、~B ~A ~A
D、~B ~A ~A ~A
been:
B(A &a):_a(a)
這個引用也是值得注意的,這里提醒大家一下,去掉引用,第一個析構是是~A
靈靈:
下面以例子說明參數為類對象,是否有初始化列表時構造與析構函數的執行順序:
vzhuzhu:
對于構造函數:基類構造函數 > 子類成員變量構造函數 > 子類構造函數
對于析構函數:子類析構函數 > 子類成員變量析構函數 > 基類析構函數
可以看出構造函數的調用過程和析構函數的調用過程正好相反。
水澤淵:
在vs上運行之后發現,輸出順序確實如@Aesthetic92所說,然而@賴聰林說的也沒有錯,可是@賴聰林舉的例子并沒有用到拷貝構造函數。
原題-----------------------------------------------------------------------------
加上拷貝構造函數---------------------------------------------------------------------- <pre name="code" class="cpp"> class A { public: A(){ cout<<"A"<<endl; } A(const A& other){ cout<<"copy A"<<endl;} ~A() { cout<<"~A"<<endl; } }; class B:public A {public:B(A &a):_a(a) {cout<<"B"<<endl; } ~B() { cout<<"~B"<<endl; } private: A _a; }; void main(void) {A a; B b(a);} //結果顯示 A A copy A B ~B ~A ~A ~A
修改后---------------------------------------------------------------------------------- class A {public: A() { cout<<"A"<<endl; } A(const A& other){ cout<<"copy A"<<endl;} ~A() { cout<<"~A"<<endl; } };class B:public A {public:B(A &a) { cout<<"B"<<endl; } ~B() { cout<<"~B"<<endl; }private: A _a; };voidmain(void){ A a; B b(a);} //結果為 A A A B ~B ~A ~A ~A
答案:選D
答案解析:答案看起來可能比較怪,其實給默認構造函數補上輸出,然后再在基類里寫個復制構造函數,這樣結果就很明朗了;
首先 A a;這個調用A的默認構造函數,
B b(a); 因為A &a,形參為引用,不需要調用基類復制構造函數(其實基類也沒寫);_a(a)首先創建對象_a,調用基類A的默認構造函數,然后調用基類復制構造函數(測試的時候可以寫出來),把a對象賦給_a,結束之后調用B的析構函數,輸出~B;然后調用基類A的析構函數撤銷復制構造函數,輸出~A;調用基類A的析構函數撤銷_a,輸出~A;最后調用基類A的析構函數撤銷一開始創建的A a,輸出~A
kuring:
要想搞明白該問題,需要理解基類構造析構函數、子類構造析構函數和子類成員變量構造析構函數的調用順序。
對于構造函數:基類構造函數 > 子類成員變量構造函數 > 子類構造函數
對于析構函數:子類析構函數 > 子類成員變量析構函數 > 基類析構函數
可以看出構造函數的調用過程和析構函數的調用過程正好相反。
main函數中首先構造變量a,然后是b。在構造b時首先調用b的基類A的構造函數,然后調用b中成員變量_a的構造函數,最后調用b的構造函數。
main函數調用結束返回時,變量的釋放順序跟變量的構造順序正好相反。首先釋放變量b,然后是變量a。
在釋放變量b時,首先調用b的析構函數,然后析構變量b的成員_a,析構_a時調用_a的析構函數。再調用b的基類的析構函數。
然后是釋放變量a,調用a的析構函數。
本例子中應該將A的析構函數更改為virtual的,防止使用多態機制時出現子類對象無法釋放的情況,本例子中沒有用到多態機制,不存在該問題。
賴聰林:
我們可以看到,這個地方先是調用parent class的構造函數,然后對成員變量C類型的構造函數,然后再最后執行B類型的構造函數。
析構的過程就是上面的過程反過來。
所以Aesthetic92的解釋有一部分不是很準確。我認為。
更加準確的說明應該是,
最開始析構b,~B,這個是沒有爭議的。
接著是析構b的成員變量_a,所以是~A
接著是b的parent class(基類)的~A
最后才是a的析構~A
不過為了理解這道題,我感覺配上我的例子更好理解一點,原題的成員變量和基類都是相同的類型,比較難以辨認。
總結
以上是生活随笔為你收集整理的构造函数和析构函数的调用过程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 右左法则----复杂指针解析
- 下一篇: 部分真题整理2