2017-04-22 247 views
0

的順序我有以下代碼一些混淆:約構造函數調用和繼承

class A { 
    public: 
     A() { cout << "A-C" << endl; } 
     ~A(){ cout << "A-D" << endl; } 
}; 

class B { 
    public: 
     B() { 
      cout << "B-C" << endl; 
     } 
     ~B() { 
      cout << "B-D" << endl; 
     } 
}; 

class C { 
    protected: 
     A* a; 
     B b; 
    public: 
     C() { 
       a = new A; 
       cout << "C-C" << endl; 
      } 
     ~C() { 
      delete a; 
      cout << "C-D" << endl; 
     } 
}; 

class D : public C { 
    protected: 
     A a; 
     B b; 
    public: 
     D(){ cout << "D-C" << endl; } 
     ~D(){ cout << "D-D" << endl; } 
}; 

int main() { 
    D* d = new D; 
    B* b = new B; 

    delete b; 
    delete d; 

    system("pause"); 
    return 0; 
} 

我在輸出最初的想法是:

A-C 
C-C 
A-C 
B-C 
D-C 
B-C 
B-D 
D-D 
B-D 
A-D 
A-D 
C-D 

但它是錯的。 輸出居然是:

B-C 
A-C 
C-C 
A-C 
B-C 
D-C 
B-C 
B-D 
D-D 
B-D 
A-D 
A-D 
C-D 
B-D 

我不知道爲什麼程序調用B的構造函數首先,析構函數最後。 我認爲構造函數調用的順序應該是這樣的: C的構造函數 - > A的構造函數 - > B的構造函數 - > D的構造函數。

和析構函數調用的順序是構造函數調用的相反順序

任何人都可以告訴我原因B的構造函數被調用的開始和B的析構函數被調用最後?

+1

等等,爲什麼輸出應該是「B-C」? 'new D'調用調用'A'構造函數的'C'構造函數。 –

+1

@GillBates nuh-huh。 'C'有一個'B'數據成員,它在構造函數的主體之前被初始化。 – Quentin

+0

@Quentin我認爲'C'中的'B'數據成員是一個指針,我的不好。 –

回答

1
B-C 
A-C 
C-C 
A-C 
B-C 
D-C 

所有這些都是由D* d = new D;造成的。

D構造函數調用構造函數C因爲CD基地。

然後,數據成員aC類的b被初始化,a是一個指針,以便沒有構造爲該數據成員呼​​叫尚未。 bB類型的對象,所以B無參數構造函數被調用,從而爲您提供第一個B-C


然後在C構造你說new A它調用的A,讓你A-C其次C-C構造。

然後,數據成員a和d類b被初始化,都是對象,因此這兩個構造函數的調用,給你A-CB-C

最後調用D構造函數,並以D-C結束。

+0

非常感謝,您的意思是說,當類從另一個類繼承時,假設D繼承自C,它將首先初始化基類的數據成員,並且構造函數將在數據成員初始化後被調用? –

+0

@KelvinNg是的,正好。 –