2013-06-29 91 views
7

空的構造讓我們看一下下面的代碼:虛擬基類調用C++(C++ 11)

class A{ 
protected: 
    int _val; 
public: 
    A(){printf("calling A empty constructor\n");} 
    A(int val):_val(val){printf("calling A constructor (%d)\n", val);} 
}; 

class B: virtual public A{ 
public: 
    B(){printf("calling B empty constructor\n");} 
    B(int val):A(val){printf("calling B constructor (%d)\n", val);} 
}; 

class C: public B{ 
public: 
    C(){printf("calling C empty constructor\n");} 
    C(int val):B(val){printf("calling C constructor (%d)\n", val);} 
}; 

int main(void) { 
    C test(2); 
} 

輸出是:

calling A empty constructor 
calling B constructor (2) 
calling C constructor (2) 

有人能向我解釋爲什麼A類構造函數被調用時沒有任何參數? 如果我希望B類從A虛擬繼承,那麼我該如何「修復」這種行爲? (如果繼承不是虛擬的 - 示例工作正常)

+0

[在虛擬繼承構造函數調用的順序]的可能重複(http://stackoverflow.com/questions/10534228/order-of-constructor-call-in-virtual-inheritance) –

+1

有沒有這被討論到死亡? –

+0

繼承中的關鍵詞「虛擬」通常會使構造函數調用基類的默認構造函數,即使您在聲明中指定了非默認構造函數(基於基類在繼承樹中多次顯示的推理)而你只想要構造函數被調用一次。另請注意,虛擬繼承的默認構造函數在正常繼承之前被調用,而不管您可能指定的順序如何。 – Immueggpain

回答

10

在C++ 03中它會是一樣的。

虛擬基礎構造函數總是從最終的葉子類中調用。 如果在實例化C時需要A的默認構造函數以外的其他內容,則必須在類C的構造函數中指定它。

C(int val): A(val), B(val) {printf("calling C constructor (%d)\n", val);}