手頭的問題很難描述,所以代碼被放在前面以獲得更好的清晰度。多繼承虛擬呼叫模糊
struct Base
{
int b;
virtual void foo(){cout << b << endl;}
Base(int x) : b(x){}
};
struct Derived1 : Base //not virtual
{
virtual void foo(){/*Derived2's code*/}
Derived1() : Base(1){}
};
struct Derived2 : Base //not virtual
{
virtual void foo(){/*Derived2's code*/}
Derived2() : Base(2){}
};
struct MultiInheritance : Derived1, Derived2
{
void bar1()
{
//needs to access Derived1's Base foo()
}
void bar2()
{
//needs to access Derived2's Base foo()
}
};
假設在有些怪異離奇的情況下,我想一個基類MultiInheritance
有兩個基類Derived1
和Derived2
有一個共同的非虛基類Base
。
有兩個Base
在MultiInheritance
,我怎麼指定我想在MultiInheritance
訪問哪些Base
類?
上面的代碼似乎很好地通過投射多次,但我不知道這是否定義的行爲。如果是這樣,編譯器如何實現它以滿足多態性的需求?一方面virtual
調用應該都產生相同的virtual
函數表,但另一方面,如果它不會輸出不同的答案。
編輯
我想強調的是,Base
類必須是非虛擬
EDIT2
深深的歉意,我嚴重歪曲了自己。上面的代碼更新更好地反映了我原來的問題。
哪一個你認爲的正確* *'Base'?或者是你的問題如何使它只有一個'Base'? – Barry
你的分析是正確的,編譯器會建立一個反映兩個基類存在的正確的vtable。爲了避免這種情況,您需要虛擬繼承,並且vtable結構將變得更加複雜。 –
您的示例中沒有任何歧義,它的行爲與書中的完全相同。 「虛擬表」是一個實現細節。沒有人在任何地方說每個實現必須每個類有一個vtbl,或者每個vtable中的每個函數簽名都必須有一個條目。實際上,對於使用vtables的任何實現來說,上述至少一個是不正確的。 –