昨天作了網易的實習生筆試(一首涼涼送給本身),其中有道問答題是這樣的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 };
結果以下:編譯器