[c++] 基類與派生類的構造與析構順序

  昨天作了網易的實習生筆試(一首涼涼送給本身),其中有道問答題是這樣的ios

 1 #include<iostream>
 2 using namespace std;
 3 class A
 4 {
 5 public:
 6     A(){cout<<"A"<<endl;}
 7     ~A(){cout<<"~A"<<endl;}
 8 
 9 };
10 
11 class B : public A
12 {
13 public:
14     B(A &a):_a(a){cout<<"B"<<endl;}
15     B(){cout<<"B"<<endl;}
16     ~B(){cout<<"~B"<<endl;}
17 private:
18     A _a;
19 };
20 
21 int main()
22 {
23     A a;
24     B b(a);
25 }

  指出基類構造函數、派生類構造函數,派生類成員變量構造函數的調用順序,並出他們的析構函數調用順序。函數

代碼運行結果以下:spa

  首先是類A的實例a,輸出第一行的「A」;由於B是A的派生類,B在實例化時會先調用A的構造函數,而後調用本身的構造函數(見連接),因此其次輸出第二行「A」和第三行「B」。.net

  而後是b的析構,先調用派生類(本身)的析構函數,將成員變量_a析構而後調用父類的析構函數,這對應第4、第五和第六行的輸出。第七行爲a的析構。3d

 

  這時候問題就來了,爲何B的成員變量_a在初始化的時候沒有調用A的構造函數?code

  原來是由於在初始化_a的時候使用了初始化列表,此時會調用A的拷貝構造函數(當咱們沒有定義拷貝構造函數時,編譯器會爲咱們定義一個),故沒有輸出「A」。blog

若咱們顯示的定義一個拷貝構造函數:get

1 class A
2 {
3 public:
4     A(){cout<<"A"<<endl;}
5     A(const A &a){cout<<"copy A"<<endl;}
6     ~A(){cout<<"~A"<<endl;}
7 
8 };

 

 

結果以下:編譯器