亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

繼承中調用構造函數/析構函數的順序

繼承中調用構造函數/析構函數的順序

C++
慕桂英4014372 2019-09-02 08:31:17
關于創建對象的一個小問題。說我有這兩個類:struct A{    A(){cout << "A() C-tor" << endl;}    ~A(){cout << "~A() D-tor" << endl;}};struct B : public A{    B(){cout << "B() C-tor" << endl;}    ~B(){cout << "~B() D-tor" << endl;}    A a;};并在主要我創建一個實例B:int main(){    B b;}請注意,B派生自A并且還具有類型的字段A。我想弄明白這些規則。我知道構造一個對象時首先調用它的父構造函數,反之亦然。字段怎么樣(A a;在這種情況下)?什么時候B創建,什么時候會調用它A的構造函數?我還沒有定義初始化列表,是否有某種默認列表?如果沒有默認列表?關于破壞的同樣問題。
查看完整描述

3 回答

?
qq_花開花謝_0

TA貢獻1835條經驗 獲得超7個贊

  • 施工總是從基地開始class。如果有多個基礎,class那么構造從最左邊的基礎開始。(旁注:如果有virtual繼承,則給予更高的偏好)。

  • 然后構造成員字段。它們按聲明的順序初始化

  • 最后,它class本身就構建了

  • 析構函數的順序正好相反

無論初始化列表如何,呼叫順序都是這樣的:

  1. Base class A的構造函數

  2. class B將構造名為a(類型class A)的字段

  3. 派生class B的構造函數


查看完整回答
反對 回復 2019-09-02
?
寶慕林4294392

TA貢獻2021條經驗 獲得超8個贊

假設沒有虛擬/多重繼承(這使事情變得復雜很多),那么規則很簡單:

  1. 分配對象存儲器

  2. 執行基類的構造函數,以大多數派生結束

  3. 執行成員初始化

  4. 該對象成為其類的真實實例

  5. 執行構造函數代碼

需要記住的一件重要事情是,直到第4步,對象還不是其類的實例,因為它只有在構造函數的執行開始后才能獲得此標題。這意味著如果在成員的構造函數期間拋出異常,則不會執行對象的析構函數,但只會破壞已構造的部分(例如成員或基類)。這也意味著如果在成員或基類的構造函數中調用對象的任何虛擬成員函數,則調用的實現將是基礎實現,而不是派生實現。另一個要記住的重要事項是,初始化列表中列出的成員將按照它們在類中聲明的順序構建,

還要注意,即使在執行構造函數代碼期間,this對象已經獲得了它的最終類(例如,關于虛擬分派),除非構造函數完成其執行,否則不會調用類的析構函數。只有當構造函數完成執行時,對象實例才是實例中真正的第一類公民...在此之前只是一個“想成為實例”(盡管有正確的類)。

破壞以完全相反的順序發生:首先執行對象析構函數,然后它丟失其類(即從對象上的這一點被視為基礎對象)然后所有成員以反向聲明順序銷毀,最后是基類銷毀過程被執行到最抽象的父級。對于構造函數,如果在基類或成員析構函數中調用對象的任何虛擬成員函數(直接或間接),則執行的實現將是父實例,因為在類析構函數完成時對象丟失了其類標題。


查看完整回答
反對 回復 2019-09-02
?
搖曳的薔薇

TA貢獻1793條經驗 獲得超6個贊

基類始終在數據成員之前構建。數據成員按照在類中聲明的順序構造。此順序與初始化列表無關。初始化數據成員時,它將查看參數的初始化列表,如果沒有匹配則調用默認構造函數。始終以相反的順序調用數據成員的析構函數。


查看完整回答
反對 回復 2019-09-02
  • 3 回答
  • 0 關注
  • 428 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號