2013-10-05 13 views
0

在下一個代碼中,構建一個C類從初始化A然後是B1,然後是B2,最後是C類。但是,在初始化B1和B2時,調試器忽略了A(1)和A(2)的初始化(出現在B1和B2的初始化列表中,但未忽略B2(3)的初始化)在C初始化列表。C++初始化列表忽略調用父類的構造函數

這是爲什麼?

在此先感謝。

下面是代碼:

struct A { 
    int i; 
    A() { i = 0; } 
    A(int _i) : i(_i) {} 
    virtual void f() { cout << i; } 
}; 

struct B1 : virtual A { 
    B1() : A(1) { f(); } 
    void f() { cout << i+10; } 
}; 

struct B2 : virtual A { 
    B2(int i) : A(2) { f(); } 
}; 

struct C : B1, B2 { 
    C() : B2(3) {} 
}; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    C* c = new C(); 
    return 0; 
} 
+0

因爲這就是虛擬繼承的工作原理。 –

+0

可否請您提供更多詳細信息:說虛擬繼承涉及時,它的初始化列表中的構造函數是否被調用是否正確? –

+1

虛擬基地由派生最多的班級構成,即「C」。 –

回答

0

這正是編譯器如何避免「死亡鑽石」。如果A(1)和A(2)被調用,意味着有基類重複初始化,這是虛擬繼承的目的 - 刪除不明確的公共基本元素。

2

對於virtual基地,最派生類必須提供的構造函數的參數,如:

struct C 
    : B1, B2 { 
    C() 
     : A(17) 
     , B2(3) {} 
}; 

如果最派生類中沒有提及virtual在其初始化列表中,使用基地的默認構造函數virtual(如果沒有,則爲錯誤)。

這樣做的原因是爲了避免派生類應該爲共享的基地提供構造函數參數的歧義:大多數派生類最清楚實際需要什麼。

相關問題