2012-02-01 39 views
4

我有下面的類結構:警告:基類「A」應該明確初始化的拷貝構造函數

class A{ 
    A(){} 
    A(const A& src){} 
}; 

class B : virtual A { 
    B():A(){} 
    B(const B& src):A(src){} 
}; 

class C : virtual A { 
    C():A(){} 
    C(const C& src):A(src){} 
}; 
class D : virtual B, virtual C { 
    D():B(),C(){} 
    D(const D& src):B(src),C(src){} 
}; 

這給了我警告:

在拷貝構造函數'd':

警告:基類 'A' 應在副本中明確初始化 構造

我不喜歡。 D的副本-Constructor調用B的copy-ctor,它稱爲copy-ctor A. 爲什麼它要求我在D中調用A的copy-ctor

如果我願意,那麼A的copy-ctor會不會被調用兩次?一旦從B調用,並且一次從D調用。

對此的任何輸入都非常感謝。

+0

它永遠不會被調用兩次。但我也沒有真正明白這一點。 – 2012-02-01 15:59:57

+4

顯示您的_real_測試用例。類定義以分號結尾,您的構造函數不是_really_「private」。 – 2012-02-01 16:01:11

+1

當我解決這些問題時,代碼片段編譯:http://ideone.com/V3ygZ所以你的問題在你的無效C++和正確的方法之間。直到我們看到您正在使用的代碼時才知道。 – 2012-02-01 16:01:37

回答

0

原因是虛擬繼承。因爲這個A應該被明確地初始化。

1

d副本-Constructor調用B的拷貝構造函數調用其A的拷貝構造函數

不,不。虛擬基類是總是由正在構建的派生類最初化。在構造器初始化器列表中初始化繼承層次結構中不是構造中的對象的派生類最多的類將被忽略。虛擬基類只能初始化一次,而規則是大多數派生類將顯式或隱式地執行此操作,如果基類不出現在正在使用的最派生類構造函數的成員初始值設定項列表中。

作爲警告提示,對於複製構造函數,您幾乎肯定希望顯式初始化正在複製的對象的虛擬基類。

2

現在我已經證實了我是正確的,B用虛擬的傳承從A

發生這種情況時,最派生類是負責​​構建基類派生。這允許多重繼承鑽石。

======== A ============ 
^  ^
    B   C 
    \   /
    \  /
     \  /
     \ /
      D 

d從B和C導出並從A,使d二者推導將繼承A的2份,一份從B和一個從C.

如果B1和B2都使用虛擬的傳承從導出A,那麼最終的類必須初始化基類,即A,從而確保只有一次實例。

這就是爲什麼你收到了錯誤信息。

相關問題