4

我知道有很多關於MI的問題,但是,似乎沒有人回答我的問題。我有以下最小的例子:多虛擬繼承

#include <iostream> 

struct Base{ 
    virtual void foo() = 0; 
}; 
struct A : public virtual Base{ 
    void foo(){ 
     std::cout << "A::foo()" << std::endl; 
    } 
    void foo(int a){ 
     std::cout << "A::foo(int a)" << std::endl; 
    } 
}; 
struct B : public virtual Base{ 
    virtual void foo(int a) = 0; 
}; 
struct C : public B,public A{ 
    using A::foo; 
}; 

int main(int argc, char* argv[]){ 
    C c; 
    c.foo(); 
    c.foo(1); 
} 

其中基地,和B是完全虛擬類和甲提供所有的實施。但是,代碼不編譯,而是給了我以下錯誤消息

mh.cpp: In function ‘int main(int, char**)’: 
mh.cpp:22:11: error: cannot declare variable ‘c’ to be of abstract type ‘C’ 
    C c; 
    ^
mh.cpp:17:12: note: because the following virtual functions are pure within ‘C’: 
struct C : public B,public A{ 
     ^
mh.cpp:15:22: note:  virtual void B::foo(int) 
    virtual void foo(int a) = 0; 

我希望可以通過擴展C類來實現

struct C : public B,public A{ 
    using A::foo; 
    void foo(int a){ 
     A::foo(a); 
    } 
}; 

但是該行爲,我寧願不添加此多餘的方法。有什麼辦法可以達到這個結果嗎?

+0

你可以添加'虛擬無效美孚(INT A)= 0;''到Base'? – songyuanyao

+2

我推薦在任何你認爲你重寫虛擬函數的地方使用C++ 11中新提供的'override'說明符。它使這樣的問題更容易找到。 –

+0

非常感謝。我認爲我可以像使用Java中的接口一樣使用虛擬類。我意識到我不能,並會相應地更新我的設計。 – user823255

回答

4

A::foo(int)不能覆蓋B::foo(int)除非A來自B

所以,如果你不想在C創建轉發覆蓋,你的選擇是:

  1. foo(int)純虛過載爲Base
  2. 使AB
  3. 重組派生你的界面讓你不需要鑽石形的虛擬繼承
+0

我想我必須在這種情況下完全使用不同的結構。令我困擾的是,使用接口在Java中可以很容易地實現相同的結構。 – user823255

1

不,如果您從純虛擬類繼承並且想要使用此派生類(聲明該類型的對象,而不是指針),則必須實現其所有純虛擬方法。 以同樣的方式,你可以問以下內容:

class A 
{ 
public: 
    virtual void foo()=0; 
    virtual void hello()=0; 
} 

class B: public A 
{ 
public: 
    void myFoo(); 
    void hello() { std::cout << "Hello!"; } 
} 

class B,我不想使用A::foo()但只有B::myFoo()我該怎麼辦?

在這種情況下,您可能需要提供純虛函數的一些虛擬實現,或重新審查你的設計......也許你不應該從繼承A.

類似的事情,你的情況。可能你的class C不應該從class B繼承。

+0

@ChrisDrew你是對的:)我的錯誤。固定。 –

0
  • 只需更換您的單行如下。
  • 衍生C只從A
  • 您的代碼

    struct C : public B,public A{ 
    using A::foo; 
    }; 
    
  • 替換上面的代碼與下面的代碼,

    struct C : public A{ 
    using A::foo; 
    }; 
    
+1

不幸的是,在那種情況下,我不能投C到B. – user823255