避免钻石继承[重复]

Posted

技术标签:

【中文标题】避免钻石继承[重复]【英文标题】:Avoiding a diamond inheritance [duplicate] 【发布时间】:2013-05-08 11:05:10 【问题描述】:

我有一堂课A

BC 是派生自类A 的接口。

      A
    /   \
   B     C

现在我必须为BC 实现DE 类。

还有一些类:FDBGDCHECIEBJDBKDCLEBMEC(而DB和@987654@3在这些类的名称末尾表示该类使用DB 作为DB 的结尾,DC 用于DCEB 用于@ 987654349@等。

所以:

class A..

class `B`: public virtual `A`..
class `C`: public virtual `A`..

class `D`: public B, public `C`..
class `E`: public B, public `C`..

class `FDB`: public `D`..
class `GDC`: public `D`..
class `HEC`: public `E`..
class `IEB`: public `E`..
class `JDB`: public `D`..
class `KDC`: public `D`..
class `LEB`: public `E`..
class `MEC`: public `E`..

但是我有一个钻石继承,我不想要它。

有人可以推荐另一种设计吗?

任何帮助表示赞赏!

【问题讨论】:

我能问一下为什么你不想要它吗?这可能就是虚拟继承的用途。 可以在here找到可能的答案。 天哪。真的吗?所有这些缩写...... 如果你告诉我们你为什么需要它,也许我们会展示一个间接解决问题的解决方案,我认为没有真正的应用程序需要这个问题。 @MM。有一些虚拟继承的巧妙应用和大多数派生的微妙之处等等,例如模拟命名模板参数(在 Vandevoorde & Josuttis 中有一个很好的部分)。但你是绝对正确的:普通用户代码应该远离如此庞大的类层次结构。 【参考方案1】:

您想要/需要避免多重继承的原因是什么?

无论哪种方式,如果在某些情况下您不能(不想)使用继承,请使用封装:

class A..

class `B`: public virtual `A`..
class `C`: public virtual `A`..

class `D`: public B 
private:
    C c_instance_;
;
class `E`: public B 
    C c_instance_;
;

... 

为避免代码重复,您可以创建一个 C(或 D)持有者,并通过受保护的继承和 CRTP 来继承它。这样,一个单独的基类拥有 C 基功能,但从它继承的类没有公共基类:

class A..

class B: public A..
class C: public A..

template<class Specialized, class DependedOn>
class DependsOn 
protected:
    DependedOn& get()  return implementation_; 
private:
    DependedOn implementation_;
;

class D: public B, protected DependsOn<D, C> .. // inheritance with CRTP
class E: public B, protected DependsOn<E, C> .. // inheritance with CRTP

class FDB: public D, protected DependsOn<FDB, B> .. 

DEFDB 等,将在内部使用get() 方法(或更具体地,DependsOn&lt;D, C&gt;::get()DependsOn&lt;E, C&gt;::get() 等)来实现公共接口。

由于DependsOn&lt;D, C&gt;DependsOn&lt;E, C&gt; 不同,您只有一个由整个层次结构实现的通用接口。

【讨论】:

以上是关于避免钻石继承[重复]的主要内容,如果未能解决你的问题,请参考以下文章

虚拟继承如何解决“钻石”(多重继承)的歧义?

为啥这个钻石类继承输出不是我期望的?

c++【钻石配置】如何用继承初始化?

python多重继承的钻石问题

我的继承和有问题的“钻石继承”一样吗

钻石(菱形)继承和虚基类