c++ - 当我想扩展当前应用程序的功能时的 DIAMOND 情况

标签 c++ multiple-inheritance virtual-inheritance diamond-problem

假设我有一个应用程序有多个类(使用继承) 现在有一天,我必须向我的应用程序添加新规范,这将需要我使用多重继承。

例如这段代码:

class A{};
class B : public A{};
class C : public A{};

现在我的新功能需要我这样做:

class D{} : public B,public C{};

但这会导致菱形问题。

所以我的问题是,如何克服这个问题: 1)作为最佳实践,我将为所有类使用虚拟继承,假设我将来可能需要使用多重继承? 或者 2) 我将简单地更改我的代码,在需要时使我的基类成为虚拟的?

最佳答案

克服这个问题的一个好方法是将您试图从类中获得的行为解耦到组件中。

现在你有这样的情况

class A {}
class B : public A {some behavior X}
class C : public A {some behavior Y}
class D : public ? {I need X and Y plus some behavior Z}

解决此问题的一种(可能不好的)方法是从 B 或 C 扩展,然后从另一个复制您需要的行为,但这是重复代码。

你可以做的是把你的行为做成组件:

class Behavior {void behave() = 0}

这将是一个我们可以称为接口(interface)的纯虚拟类。然后你可以这样做:

class BehaviorX : public Behavior {void behave(){behavior x}}
class BehaviorY : public Behavior {void behave(){behavior y}}
class BehaviorZ : public Behavior {void behave(){behavior z}}

这将允许您创建从 A 扩展的新类,但您可以选择它们具有的行为:

class D : public A {BehaviorX, BehaviorY, BehaviorZ, ...}

如果您真的想将组件建模提升到一个新的水平,您可以摆脱将所有子类都放在一起,而只需将类 A 作为一个组件包,它可以使用您可以想到的任意数量的行为,然后您可以只需在任何你想要的地方创建新的“类”,它们只有你想要的行为:

A likeB = new A(BehaviorX);
A likeC = new A(BehaviorY);
A likeD = new A(BehaviorX, BehaviorY, BehaviorZ);
A likeE = new A(BehaviorY, BehaviorZ, Behavior?);

关于c++ - 当我想扩展当前应用程序的功能时的 DIAMOND 情况,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41823925/

相关文章:

c++ - 如何在 SQLite 数据库中存储枚举

c++ - 为什么 const/non-const 函数重载的继承不明确?

c++ - 如果一个父类是一个接口(interface),可以使用多重继承吗?

c++ - 如何检测和断言特定类的虚拟继承?

c++ - C++中的虚拟继承被误解了

c++ - 'MSize' 不是 cv::Mat 的成员

c++ - vector<T>.erase() 与 g++ 的问题

c++ - 冲突的不匹配标签与标准库一起编译,但不以其他方式编译

c++ - 多重继承和多态问题

c++ - 虚拟继承、显式实例化——返回派生类引用/指针(协变类型)