2014-01-17 139 views
2

我試圖實現以下類:C++多重和虛擬繼承

class a { 
public : 
    //... 
    f(); 
    //... 
}; 

class b : virtual public a { 
public : 
    //... 
    f(); 
    //... 
} 

class c : virtual public a { 
public : 
    //... 
    f(); 
    //... 
} 

class d : virtual public c { 
public : 
    //... 
    f(); 
    //... 
} 

class e : public b, public d { 
public : 
    //... 
} 

但是編譯器告訴我,爲成員函數f()的要求是不明確的。 我想'e'繼承'd'的f()版本(所以'c'),但只有在'e'中重新聲明f()時纔會編譯代碼。所以,我只能編譯如果我如下的代碼「E」的構造函數:

e::e(...) : a(...), c(...), b(...), d(...) 
{ 
} 

這似乎不合邏輯對我來說,因爲從「C」「d」 inherate和「b」將首先建造。

回答

1

e爲從B & d繼承,所以公司的F B版()和f的d()版本。

這是非常合乎邏輯的,有歧義。

如果你想E級使用F(d的版本),有兩種方法,

  1. 調用d :: f()的直接調用

    instance_e.d::f(); //will call d::f().

  2. 重新聲明d :: f()的在電子

    class e : public b, public d { public : using d::f; }

我不明白你爲什麼在這裏提到的構造,敷設渠道的訂單有沒有影響到函數f()。

+0

+1 - '用d :: F;'是一個不錯的選擇。第三種方法是添加'void f(){d :: f(); }'to'class e' - 在這裏沒有必要,但有時在修改參數時有用,記錄添加等等。 –

+0

這只是因爲我不會不確定編譯器爲什麼要按照特定的順序構建構造函數,因爲,在我看來,b是要先建成的。謝謝你的回答,但我會使用'使用'方法。 – Kernael

2

它不與建築或聲明的順序關係。如果有兩個基類具有相同的方法名稱,編譯器無法確定您打算調用哪一個。在你的情況下,你在類b和類d中都有一個被覆蓋的f()的版本。

於是撥打電話明確。 b :: f()或d :: f()。