![](/img/trans.png)
[英]Virtual tables and virtual pointers for multiple virtual inheritance and type casting
[英]diamond inheritance virtual member casting with pointers
與這個問題類似,但不相同:
A
/ \
B C
\ /
D
我想要的是:
struct A { virtual void func (void) = 0; };
struct B : virtual A { void func (void) {} };
struct C : virtual A { void func (void) {} };
struct D : B,C { void func (void) {} };
int main ()
{
A *p = new D();
((C*) p)->func(); // do C::func
((B*) p)->func(); // do B::func
}
根據這個問題,這似乎不是問題,只要繼承只是多重繼承而不是鑽石即可。 為什么這不適用於菱形形狀?
顯然它是模棱兩可的,但是我想做的是強制轉換指針,因此使用了虛函數的另一個父實現,即:
((C*) p)->func(); //does C::func
如果運行上面的代碼,則會遇到錯誤:
error: cannot convert from pointer to base class 'A' to pointer to derived class 'C' because the base is virtual
((C*)p)->func();
我試圖谷歌,但找不到任何地方
由於func
在整個層次結構中都是虛擬的,因此通過指向所涉及的任何類型的指針對func
任何直接調用都將調用D::func
。 要進行問題代碼的轉換,請使用dynamic_cast<C*>(p)
。 但這並不能消除func
的虛擬性,因此最終會像p->func()
一樣調用D::func
。
要擺脫虛擬性,您必須命名類以及函數。 在更簡單的上下文中:
D *d = new D;
d->C::func(); // calls C::func
當您擁有指向基本類型的指針而不是指向派生類型的指針時,必須將指針轉換為具有C::func
的類型。 該轉換是通過dynamic_cast
完成的,如下所示:
A *p = new D;
dynamic_cast<C*>(p)->C::func();
根據您的編譯器,您可能需要稍微修改類定義才能擺脫鏈接器錯誤。 一些編譯器會混淆沒有非內聯函數的類的繼承。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.