【发布时间】:2012-07-12 18:58:45
【问题描述】:
感谢观看。
我正在通过 c++ 中的软件模式来熟悉它,但我遇到了基于接口的编程问题 - 即菱形问题。
情况如下:有一个Widget 类,从该类派生一个Button 类,每个类都有自己的接口类。 Widget 类有foo 方法,Button 类有Widget 的foo 方法和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 的(纯虚拟)。但是通过在IButton 和CWidget 中使用虚拟继承,它会编译并运行,将'foobar' 打印到屏幕上。
但问题是 Eclipse 将 CButton button 标记为错误:
The type 'CButton' must implement the inherited pure virtual method 'IWidget::foo'
这很奇怪,因为一切都按预期运行。这是 Eclipse 的语法检查器的问题吗?我知道这个问题还有其他解决方案,所以也许 Eclipse 试图告诉我我的方法不标准?
非常感谢任何帮助。
编辑:我在 OSX Lion 上使用 gcc 4.2,以及最新版本的 Eclipse for c++。
【问题讨论】:
-
您真的需要将
CButton视为IWidget和IButton吗? -
我可以定义
IButton以包含foo和bar方法。我是 C++ 的新手,所以也许这可能是首选方法(它具有清晰的好处,因为查看IButton会告诉你所有CButton的功能)但是如果有foo1怎么办?foo2, ...,foo30IWidget 中的方法?我必须将它们全部复制到 IButton,更改 IWidget 中的任何内容都意味着手动更改 IButton。 -
您使用的是什么编译器(请注意,“eclipse”不是 C++ 编译器)。 gcc 4.7 可以很好地构建您的示例。
-
只是为了好玩,这里有一个不同的钻石继承解决方案link。他使用模板,因此(使用我的示例)
CButton继承CWidget,后者继承IButton,后者继承IWidget。问题是实例化一个小部件需要Widget<IWidget> mywidget;(即,您必须明确地将接口类放在尖括号中)。 -
问题是 gcc 不能用于提供 CDT 所需的信息以执行智能自动完成之类的操作。 Gcc 根本不会提供有关该程序的足够信息。不管你信不信,这是出于意识形态的原因。
标签: c++ eclipse diamond-problem