gpt4 book ai didi

c++ - 我怎样才能避免菱形继承(钻石问题)?

转载 作者:太空狗 更新时间:2023-10-29 20:54:44 31 4
gpt4 key购买 nike

我目前正在从事 C++ 设计,其中我具有以下继承结构:

  A
/ \
B C

A执行两个类共有的计算 BC和类 BC有两种不同的初始化方式 A .

我想添加某种混合初始化,即类 D将使用 B 中的方法和 C .

但是,我需要使用菱形继承(钻石问题)才能访问 B::init()C::init()设置 D 的属性.

我知道我可以使用虚拟继承来避免菱形问题,但是我遇到了运行时错误,而我手动复制方法时不会遇到这些错误。此外,我在尝试实例化类时遇到问题 BC ,一位同事建议我永远不要在我的设计中使用菱形继承。

因此,我想找到某种“干净”的解决方法,但我一直没能做到。

  • 我可以将所有初始化例程放在类 A 中, 但目前它们很好地分开了,我想避免有一个大类,在那里我无法真正分离类的不同功能组 BC .回答后编辑:这是我选择的,使用不同的 cpp 文件将我的“大”类拆分为逻辑方法组。

  • 我还可以删除继承链接并用友元替换它们,其中 B 的方法和 C是静态的并且处理类型为 A* 的指针.这样,我可以调用 B::init(A* a)C::init(A* a)来自 D::init(A* a) .但是,我必须替换 _fooAttribute 的所有用途通过 a->_fooAttribute ,这有点麻烦,似乎也不对。

你会推荐什么?

最佳答案

如果您的设计需要菱形继承,那么这就是您需要做的。人们将它视为 C++ 的“不得使用”功能,但事实是它就在那里,它是完全定义的(如果理解起来有点复杂),如果您的问题空间需要它,您应该使用

特别是,我无法理解这是否确实是菱形继承(钻石问题)。特别是 B 中的 AC 中的 A 是否相同 <A 的 em>实例?从您的问题看来,事实并非如此。 BC 都有某种不同的方式来初始化 A。如果是这样的话,这就不是菱形继承(钻石问题)了。只需确保 BC 在非虚拟继承中继承 A

话虽如此,请确保这确实是您的设计所要求的。你能诚实地说 B 是一个 A 吗?那个 C?你能诚实地说 D 既是 B 又是 C 吗?如果不是,可能使 A 成为 BC 或两者的成员,或者使 B D 的 C 成员更有意义。

如果您从 A 继承的唯一原因是作为扩展 A 提供的方法的一种方式,那么考虑简单地使这些方法成为 的成员一个。如上所述,虽然减少代码重复是一项有值(value)的事业,但设计应确保继承关系是一种是一种关系。偏离这一点就是自找麻烦。

关于c++ - 我怎样才能避免菱形继承(钻石问题)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38267016/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com