C++ 这可以通过多重继承来实现吗?

C++ 这可以通过多重继承来实现吗?,c++,multiple-inheritance,C++,Multiple Inheritance,这是我想做的 假设我有一个班级小部件 然后我从小部件创建按钮 然后我创建ModifiedWidget,它重新实现小部件的某些功能 然后我希望按钮使用ModifiedWidget而不是普通的小部件。这有可能做些什么吗 谢谢 class Button : public Widget; class SuperButton : public Button, public ModifiedWidget; 我只是不确定这是否能达到我想要的效果。最简单的方法是使用封装,而不是继承 class Button

这是我想做的

假设我有一个班级小部件

然后我从小部件创建按钮

然后我创建ModifiedWidget,它重新实现小部件的某些功能

然后我希望按钮使用ModifiedWidget而不是普通的小部件。这有可能做些什么吗

谢谢

class Button : public Widget;

class SuperButton : public Button, public ModifiedWidget;

我只是不确定这是否能达到我想要的效果。

最简单的方法是使用封装,而不是继承

class Button
{
    Button(Widget * w) { mywidget = w; }
    Widget * mywidget;
};
另一种方法是让Button成为模板类

template<class Parent>
class Button : Parent
{
};

Button<Widget> mybutton1;
Button<ModifiedWidget> mybutton2;
模板
类按钮:父类
{
};
按钮mybutton1;
按钮mybutton2;

最简单的方法是使用封装,而不是继承

class Button
{
    Button(Widget * w) { mywidget = w; }
    Widget * mywidget;
};
另一种方法是让Button成为模板类

template<class Parent>
class Button : Parent
{
};

Button<Widget> mybutton1;
Button<ModifiedWidget> mybutton2;
模板
类按钮:父类
{
};
按钮mybutton1;
按钮mybutton2;

如果我理解了你的问题,这是典型的

尽管我建议重新考虑您的设计,但如果小心一点,这是可能的,因为多重继承通常可以避免(这会带来更简单、更干净的设计)

还有可怕的钻石

作为对示例的回应,您必须对Button和ModifiedWidget类使用虚拟继承

class Button : public virtual Widget;

class ModifiedWidget : public virtual Widget;

如果我理解了你的问题,这是典型的

尽管我建议重新考虑您的设计,但如果小心一点,这是可能的,因为多重继承通常可以避免(这会带来更简单、更干净的设计)

还有可怕的钻石

作为对示例的回应,您必须对Button和ModifiedWidget类使用虚拟继承

class Button : public virtual Widget;

class ModifiedWidget : public virtual Widget;
将它们分开:

class Widget {
    ...
    virtual void some_function();
};

class ModifiedWidget : public Widget {
    ...
    // override the base version of this method
    virtual void some_function();
};

class Button {
    Button(Widget* w) : widge(w) { }
    Widget* widge;
};

class SuperButton : public virtual Button {
    SuperButton(Widget* w) : Button(w) { }
};
现在,您的
小部件
有了层次结构,您的
按钮
也有了自己的层次结构。说你的按钮包含一个小部件可能比说你的按钮是一个小部件更有意义。因此,我们对按钮小部件关系使用封装而不是继承,但仍然分别对按钮和小部件进行继承。

将它们分开:

class Widget {
    ...
    virtual void some_function();
};

class ModifiedWidget : public Widget {
    ...
    // override the base version of this method
    virtual void some_function();
};

class Button {
    Button(Widget* w) : widge(w) { }
    Widget* widge;
};

class SuperButton : public virtual Button {
    SuperButton(Widget* w) : Button(w) { }
};

现在,您的
小部件
有了层次结构,您的
按钮
也有了自己的层次结构。说你的按钮包含一个小部件可能比说你的按钮是一个小部件更有意义。因此,对于按钮和小部件的关系,我们使用封装而不是继承,但是仍然分别对按钮和小部件进行继承。

这不是一个很好的问题。正如它所写的,听起来好像你只是改变了父按钮的来源。请澄清。这不只是
类小部件{…}的一个例子吗;类ModifiedWidget:公共小部件{…};类按钮:公共ModifiedWidget{…}?还不清楚你的问题是什么!现在听起来这是一种相当标准的多重继承关系(尽管是钻石关系)。@Milo那么你在问什么。只需更改按钮即可从ModifiedWidget派生。没有多重继承,为什么要这么做。现在,即使这样做有效,您也会要求编译器预期Widget方法的两种不同实现。我可以理解钻石是一个问题,但你在做一个三角形。不是很好的问题。正如它所写的,听起来好像你只是改变了父按钮的来源。请澄清。这不只是
类小部件{…}的一个例子吗;类ModifiedWidget:公共小部件{…};类按钮:公共ModifiedWidget{…}?还不清楚你的问题是什么!现在听起来这是一种相当标准的多重继承关系(尽管是钻石关系)。@Milo那么你在问什么。只需更改按钮即可从ModifiedWidget派生。没有多重继承,为什么要这么做。现在,即使这样做有效,您也会要求编译器预期Widget方法的两种不同实现。我可以理解钻石是一个问题,但你正在制造一个三角形。封装不能很好地反映Liskov原理:按钮是一个小部件,按钮用户希望将其用作小部件。模板化版本使用小部件作为一个组件解决了这个问题mixin@AndyT,我发现is-a关系太容易假设,而且通常可以不费吹灰之力地改变。不确定这个案例,这就是为什么我给出了二对一的答案。Button和SuperButton可能有不同的实现。所以他可能需要延长按钮,但我们得到了什么?模板方法比多重继承更复杂。封装不能很好地反映Liskov原理:按钮是一个小部件,按钮用户希望将其用作小部件。模板化版本使用小部件作为一个组件解决了这个问题mixin@AndyT,我发现is-a关系太容易假设,而且通常可以不费吹灰之力地改变。不确定这个案例,这就是为什么我给出了二对一的答案。Button和SuperButton可能有不同的实现。所以他可能需要延长按钮,但我们得到了什么?模板方法比多重继承更复杂。