2010-02-09 42 views
6

假設我有一個菱形繼承情況如下:爲什麼下面的類有一個虛擬表?

class A{ 
    public: virtual void foo(){}; 
}; 
class B: public virtual A{ 
    public: virtual void foo(){}; 
}; 
class C: public virtual A{ 
    public: virtual void foo(){}; 
}; 
class D: B, C{}; 

最後一行產生了編譯錯誤引用歧義。據我瞭解,問題在於編譯器不知道在D的vtbl中放置哪個foo,但是爲什麼如果它沒有定義它自己的虛擬函數,甚至會存在D的vtbl?

+0

「虛擬」作爲保護級別說明符,即使在您的類聲明行上有效(例如,類B:虛擬A)? – Joe 2010-02-09 00:52:13

+4

這不是保護說明符。它表示一個虛擬的基類,這是一種解決鑽石問題的法律手段。 – 2010-02-09 00:53:43

+0

啊,對,謝謝。 – Joe 2010-02-09 01:03:04

回答

7

您正在繼承包含虛函數的類。因此,你的班級有虛擬功能。就這麼簡單。

+0

那麼也許我錯過了一些東西,因爲當我從繼承規範(類B:A,類C:A)中移除單詞「虛擬」時,它會編譯並運行。難道不應該因爲我「繼承包含虛函數的類」而出現問題嗎? – EpsilonVector 2010-02-09 00:57:48

+0

對不起,這是B類:公共A,依此類推... – EpsilonVector 2010-02-09 01:02:45

+0

從'B類'和'C類'的方法聲明中刪除關鍵字'virtual'。重新編譯,看看會發生什麼。 – 2010-02-09 01:05:05

相關問題