【问题标题】:Got diamond inheritance working, but Eclipse still complains得到钻石继承工作,但 Eclipse 仍然抱怨
【发布时间】:2012-07-12 18:58:45
【问题描述】:

感谢观看。

我正在通过 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 不仅继承了CWidgetfoo,还继承了IButton 的(纯虚拟)。但是通过在IButtonCWidget 中使用虚拟继承,它会编译并运行,将'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 视为IWidgetIButton 吗?
  • 我可以定义 IButton 以包含 foobar 方法。我是 C++ 的新手,所以也许这可能是首选方法(它具有清晰的好处,因为查看 IButton 会告诉你所有 CButton 的功能)但是如果有 foo1 怎么办? foo2, ..., foo30 IWidget 中的方法?我必须将它们全部复制到 IButton,更改 IWidget 中的任何内容都意味着手动更改 IButton。
  • 您使用的是什么编译器(请注意,“eclipse”不是 C++ 编译器)。 gcc 4.7 可以很好地构建您的示例。
  • 只是为了好玩,这里有一个不同的钻石继承解决方案link。他使用模板,因此(使用我的示例)CButton 继承 CWidget,后者继承 IButton,后者继承 IWidget。问题是实例化一个小部件需要Widget&lt;IWidget&gt; mywidget;(即,您必须明确地将接口类放在尖括号中)。
  • 问题是 gcc 不能用于提供 CDT 所需的信息以执行智能自动完成之类的操作。 Gcc 根本不会提供有关该程序的足够信息。不管你信不信,这是出于意识形态的原因。

标签: c++ eclipse diamond-problem


【解决方案1】:

对我来说它看起来很标准。我的参考资料是 Stroustrup 的“The C++ Programming Language”,第 3 版,15.2.5.1,关于菱形继承。他写道,“两个不同的类可能会覆盖来自虚拟基类的不同虚拟函数。这样,​​几个派生类可以为虚拟基类提供的接口贡献实现。”他的示例与您的示例具有相同的结构。这是虚拟继承的重要组成部分。

【讨论】:

  • 我不确定这是否会有所帮助,但您可以尝试将using CWidget::foo; 添加到CButton。这用于解决多重继承中的歧义。请参阅第 15.2.2 节。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-16
  • 1970-01-01
  • 1970-01-01
  • 2023-03-16
  • 2020-10-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多