2010-08-19 136 views
16

可能有類的虛擬繼承不提供默認構造函數?默認的構造函數和虛擬繼承

目前的菱形圖(最簡單的一個,沒有提供默認的構造函數)沒有編譯(g ++ 4.4.3)。

class A { 
public: 
    A(int) {} 
}; 
class B : virtual public A { 
public: 
    B(int i) : A(i) {} 
}; 
class C : virtual public A { 
public: 
    C(int i) : A(i) {} 
}; 
class D : public B, public C { 
public: 
    D(int i) : B(i), C(i) {} 
}; 

感謝, 弗朗切斯科

回答

3

我相信你D類還需要顯式調用A的在它的初始化列表構造。

22

你需要調用A的構造這裏明確

D(int i) : A(i), B(i), C(i) {} 

虛基類的特別之處在於它們是由最派生類而不是從虛擬繼承任何中間基類初始化基礎。哪個潛在的多個初始化器可以正確選擇初始化一個基地址?

如果最派生類被構造在其成員列表initalization則虛擬基類與必須存在且可訪問其默認的構造初始化沒有列出它。

無恥地從here複製:-)

1

的多布斯醫生文章Multiple Inheritance Considered Useful解釋處理這個問題的各種方法。這個建議基本上是提供默認的構造函數和方法。它增加了更多的工作,爲B和C,但防止d自不必瞭解A.

+1

離開d不知道A的,當然,理想的。在「的init()」的解決方案,不幸的是,有一個缺點:A的構造將被調用兩次(一次由每個B和C)可具有副作用(特別是如果使用靜態成員)。另外,如果開發人員創建'class D:public A {}',則可能根本不會調用'init()'方法,使對象保持未初始化狀態。 – Marste 2015-08-12 13:05:59

0

你需要顯式調用的結構是這樣的:

D(int i) : A(i), B(i), C(i) {}