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