2009-10-01 32 views
5
class Base 
{ 
     public: 
     int i; 

     Base() 
     { 
      cout<<"Base Constructor"<<endl; 
     } 

     Base (Base& b) 
     { 
      cout<<"Base Copy Constructor"<<endl; 
      i = b.i; 
     } 


     ~Base() 
     { 
      cout<<"Base Destructor"<<endl; 
     } 

     void val() 
     { 
      cout<<"i: "<< i<<endl; 
     }  
}; 

class Derived: public Base 
{ 
     public: 
     int i; 

     Derived() 
     { 
      Base::i = 5;  
      cout<<"Derived Constructor"<<endl; 
     } 

     /*Derived (Derived& d) 
     { 
      cout<<"Derived copy Constructor"<<endl; 
      i = d.i; 
     }*/ 

     ~Derived() 
     { 
      cout<<"Derived Destructor"<<endl; 
     }  

     void val() 
     { 
      cout<<"i: "<< i<<endl; 
      Base::val(); 
     } 
}; 

如果我做 派生的d1; 導出的d2 = d1; 調用base的拷貝構造函數,並調用derived的默認拷貝構造函數。未調用的基本複製構造函數

但是,如果我從派生的複製構造函數中刪除註釋基本副本構造函數不會被調用。這有什麼特別的原因嗎? 在此先感謝。

+3

IMVHO http://www.parashift.com/c++-faq-lite/ctors.html是理解C++構造函數的極好資源。 (實際上,C++ FAQ Lite通常是高級初學者的一個難以置信的信息源。) – notJim 2009-10-01 04:53:17

+0

我認爲你的基礎析構函數應該是虛擬的。 – 2013-09-08 18:52:19

回答

13

如果你想讀的實際規則,你應該參考C++標準12.8/8:

類X的隱式定義的拷貝構造函數執行它的子對象的成員複製。 複製順序與用戶定義的構造中的基礎和成員的初始化順序相同(見12.6.2)。每個子對象都以適合其類型的方式進行復制:

  • 如果子對象是類類型,則使用該類的複製構造函數;
  • 如果子對象是數組,則每個元素都以適合元素類型的方式被複制;
  • 如果子對象是標量類型,則使用內置賦值運算符。

當你定義拷貝構造函數明確你應該調用基類的拷貝C-TOR明確。

16

我認爲你必須明確地調用基複製構造函數:

Derived (Derived& d) : Base(d) 
    { 
     cout<<"Derived copy Constructor"<<endl; 
     i = d.i; 
    } 
4

在你Derived拷貝構造函數,你需要添加以下內容:

Derived (const Derived &d) : Base(d) { } 
2

C++不做任何形式的「構造函數匹配」。如果你沒有明確地調用基類的構造函數,那麼調用默認的構造函數(在技術上,基類子對象是「值初始化的」,但對於具有構造函數的類來說,這是相同的事情)。

1

您應該閱讀this:它解釋了繼承&特殊成員(如構造函數)是如何工作的。

0

非常感謝。我知道了。這意味着基類複製構造函數的調用在派生的默認拷貝構造函數中自動完成。而在第二種情況下,因爲我正在編寫派生的複製構造函數,所以我必須對基礎的複製構造函數進行顯式調用。再次感謝