2012-07-12 61 views
3

感谢您的期待。钻石继承工作,但Eclipse仍然抱怨

我正在使用C++中的软件模式来熟悉它,并且在基于接口的编程中遇到问题 - 即钻石问题。

情况如下:有一个Widget类,其中派生了一个Button类,每个类都有它们自己的接口类。 Widget类具有foo方法,Button类具有Widgetfoo方法和bar方法。

#include <iostream> 
using namespace std; 

class IWidget{ 
public: 
    virtual void foo() = 0; 
    virtual ~IWidget() {} 
}; 

class IButton : virtual public IWidget{ 
public: 
    virtual void bar() = 0; 
    virtual ~IButton() {} 
}; 

class CWidget : virtual public IWidget{ 
public: 
    void foo(){ cout << "foo"; } 
}; 

class CButton : public CWidget, public IButton{ 
public: 
    void bar() { cout << "bar"; } 
}; 


int main(){ 
    CButton button; 
    button.foo(); 
    button.bar(); 
} 

所以问题是,CButton的不仅CWidget继承的foo,也IButton的(这是纯虚拟的)。但是通过在IButtonCWidget中使用虚拟继承,它编译并运行,将'foobar'打印到屏幕上。

但问题是,Eclipse的颓势CButton button为错误:

The type 'CButton' must implement the inherited pure virtual method 'IWidget::foo' 

这是奇怪的,因为一切都运行正常。这是Eclipse的语法检查器的问题吗?我知道这个问题还有其他解决方案,所以也许E​​clipse试图告诉我,我的方法不是标准的?

任何帮助将非常感激。

编辑:我在OSX Lion上使用gcc 4.2,并在C++上使用最新版本的Eclipse。

+0

你真的需要能够把'CButton'当成'IWidget'和'IButton'吗? – 2012-07-12 19:10:51

+0

我可以将'IButton'定义为包含'foo'和'bar'方法。我是新来的C++,所以也许这可能是首选的方法(它具有清晰度的好处,因为看看'IButton'告诉你所有'CButton'的功能) 但是,如果有'foo1 ','foo2',...,'foo30'方法在IWidget中?我必须将它们全部复制到IButton,并且在IWidget中更改任何内容都意味着要手动更改IButton。 – user1521676 2012-07-12 19:17:20

+0

你在使用什么编译器(注意“eclipse”不是C++编译器)。 gcc 4.7构建你的例子很好。 – 2012-07-12 19:26:01

回答

0

它对我来说很标准。我的参考是关于钻石继承的Stroustrup的“The C++ Programming Language”,第3版,15.2.5.1。他写道:“两个不同的类可能会覆盖虚拟基础中的不同虚拟功能,这样,几个派生类可以为虚拟基类提供的接口提供实现。”他的例子与你的例子有相同的结构。这是虚拟继承的重要组成部分。

+0

我不确定这是否会有所帮助,但您可以尝试在'CButton'中添加'使用CWidget :: foo;'。这用于解决多重继承中的歧义。参见第15.2.2节。 – 2015-05-06 20:54:02