当我想扩展当前应用程序的功能时,出现DIAMOND情况
DIAMOND situation when I want to extend the functionality of my current application
假设我有一个应用程序,它有多个类(使用继承)现在有一天,我必须向我的应用程序添加新的规范,这将要求我使用多重继承。
例如这个代码:
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}
这将是一个我们可以调用接口的纯虚拟类。然后你可以做:
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?);
相关文章:
- 在以下情况下会出现什么问题?
- 为什么在重载区域函数时在波纹管代码的情况下会出现歧义
- 当我尝试在启用推理引擎的情况下编译 OpenCv 时,出现错误
- 在没有 UWP 的情况下从 C++/WinRT 使用 FileOpenPicker 时出现视觉"Invalid window handle"错误
- SIGABRT 运行时何时出现错误以及如何在这种情况下进行调试
- 当我想扩展当前应用程序的功能时,出现DIAMOND情况
- 为什么仅在列表初始化的情况下才会出现狭窄的转换警告
- C++ 标准库堆栈使用情况.推送浮点数组时出现问题
- 如何遍历二叉树并在不传递值的情况下计算值的出现次数
- 如何消除只在启用优化的情况下出现的错误
- 如何在不出现C2227错误的情况下调用此方法
- 在启用 OpenCL 选项的情况下使用 Tesseract 时出现 malloc 错误
- 在这种情况下,DirectX COM 对象会出现内存泄漏
- 在任何情况下都会出现意外输出.我的解决方案出了什么问题
- 同时检查两个向量中值的出现情况
- OpenGL错误只在未经调试的情况下运行时出现,怎么可能呢
- 在不使用动态数组的情况下初始化数组时出现问题
- 为什么在使用C++模板的这两种情况下会出现差异
- 在vsync打开的情况下执行glTexImage2D时出现奇怪的延迟
- 查找字符串中某个字符的所有出现情况