2016-08-16 75 views
0

我知道編譯器給出歧義的錯誤,如果我們沒有提到虛擬關鍵字,而導出鑽石問題中的子類。那麼虛擬關鍵字如何消除這種歧義?虛擬關鍵字如何解決多繼承中的歧義問題?

+6

明顯的重複:[虛擬繼承如何解決「菱形」(多繼承)歧義?](http://stackoverflow.com/q/2659116/1149924) – kkm

回答

0

isocpp faq

class Base { 
public: 
    // ... 
protected: 
    int data_; 
}; 
class Der1 : public virtual Base { 
        ↑↑↑↑↑↑↑ // This is the key 
public: 
    // ... 
}; 
class Der2 : public virtual Base { 
        ↑↑↑↑↑↑↑ // This is the key 
public: 
    // ... 
}; 
class Join : public Der1, public Der2 { 
public: 
    void method() 
    { 
    data_ = 1; // Good: this is now unambiguous 
    } 
}; 
int main() 
{ 
    Join* j = new Join(); 
    Base* b = j; // Good: this is now unambiguous 
} 

如果沒有指定繼承虛擬,編譯器會嘗試在Derived對象添加兩個Base類,那就不知道哪data_填寫你會有兩個在你的派生類中相同的對象。 聲明繼承爲virtual告訴編譯器,您只需要派生類中的基類的一個實例。

+0

謝謝dau_sama。在這種情況下,Join類的大小是12,其中包括2個虛擬指針Der1,Der2和4個data_(我認爲)。這是對的嗎?編譯器還使用哪個路徑來維護Base對象的單個副本? – DevMJ

+0

我認爲這在gcc/x86中是正確的,但它是實現定義的。可能在其他架構上,它可能以不同的方式實現。 在這種簡單的情況下,編譯器只知道它只需要在內存佈局中保留一個實例的基礎對象。 –