簡體   English   中英

鑽石繼承虛擬成員的指針轉換

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM