【问题标题】:DIAMOND situation when I want to extend the functionality of my current application当我想扩展我当前应用程序的功能时的 DIAMOND 情况
【发布时间】:2017-01-24 08:59:40
【问题描述】:

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

例如这段代码:

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

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

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

但这会导致钻石问题。

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

【问题讨论】:

  • 您的 Y 继承不是问题。你需要以A 威胁D 吗?
  • 虚拟继承有一些强约束,特别是对于整个层次结构中所需的构造函数。
  • 你看到了吗(stackoverflow.com/a/407928/2721583)?您可以修改代码以使用接口而不是具体的基类。
  • 不存在“钻石问题”。
  • 钻石继承有问题吗?你能写成:class A {...}; class CMixin {...}; class C: public A, public CMixin {}; class D : public B, public CMixin {};吗?这里有很多选择。

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


【解决方案1】:

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

现在你有这样的情况

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}

这将是一个纯虚类,我们可以称之为接口。然后你可以这样做:

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?);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-05
    • 1970-01-01
    • 1970-01-01
    • 2016-08-22
    • 1970-01-01
    • 2017-04-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多