【问题标题】:Diamond inheritance of interfaces (C++)接口的菱形继承 (C++)
【发布时间】:2018-12-28 03:03:30
【问题描述】:

我偶然发现了一个钻石继承问题,我不确定最佳解决方案。以下代码有效且没有菱形问题:

class Element { /* pure virtual functions */ };
class Diode : public Element {};
class Thyristor : public Diode {};

虽然我不喜欢公共继承,因为晶闸管不是二极管,它只是经常像二极管一样工作,我想使用很多二极管代码。我可以通过使用组合而不是继承来使其工作,但这会导致二极管和晶闸管之间的内部数据结构重复,这是我不喜欢的。我想做的是使用私有继承。如果我这样做,那么晶闸管也需要从 Element 公开继承:

class Thyristor : public Element, private Diode {};

潜在的问题是我现在创建了一个菱形,因为 Element 是直接通过 Diode 继承的。如果 Element 是纯虚函数,这是一个问题吗?如果是,解决这个问题的正确方法是什么,只对晶闸管类进行更改?

【问题讨论】:

  • "composition ... 导致二极管和晶闸管之间的内部数据结构重复"你能说明为什么在这种情况下重复是不可避免的吗?
  • 在没有看到更多代码的情况下无法确定,但我的直觉认为class Thyristor : public Element, private Diode {}; 不太可能是一个好的选择。如果Element 是一个接口,那么您绝对应该从它获得公共继承。至于Diode和Thyristor怎么看,Thyristor好像不是“是”Diode,所以不要继承。
  • 尝试从Diode 和Thyristor 中分解出常见的数据结构和功能。例如如果两者都需要一组相同的热属性,请在它们之外定义一个 ThermalProperties 结构,并为每个 Diode 和 Thyristor 一个成员。
  • 仅使用继承来消除代码重复是一种可疑的代码气味。我担心你用这种方式使用继承会产生比你解决的问题更多的问题。

标签: c++ inheritance


【解决方案1】:

在这种情况下,您当然应该使用聚合而不是继承。

回溯并问自己:为什么我要在这里继承?晶闸管和二极管如何在外部代码中使用?很快你就会发现你不需要继承元素,只需要聚合必要的行为(接触数量、传导行为等)

【讨论】:

    猜你喜欢
    • 2012-10-16
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-24
    • 1970-01-01
    • 2023-03-14
    相关资源
    最近更新 更多