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

Posted

技术标签:

【中文标题】我的继承和有问题的“钻石继承”一样吗【英文标题】:Is my inheritance the same as the problematic "diamond inheritance" 【发布时间】:2022-01-12 15:04:49 【问题描述】:

我有多个虚拟基类,它们为我的实现类创建接口。然而,我希望他们都能够序列化和反序列化自己。这将导致以下 ABC 继承:

假设我有一个类A,它允许对类进行序列化和反序列化。

class A
  virtual void serialize() = 0;
  virtual void deserialize() = 0;

我有一个 B 类,它添加了一些虚拟调用,但也必须能够处理它自己的序列化操作:

class B : public A 
  B() : A() 
    some_variable_B_is_responisble_for = 0;
  

  // inherited from A
  virtual void serialize() 
  virtual void deserialize() 

  
  virtual void Bfunction() = 0;
private:
  int some_variable_B_is_responisble_for;

现在我有一个 C 类,它实现了 A 和 B 的功能。在以下模式中:

 A
^ ^
| |
| B
| ^
| |
 C
class C : public A, public B
  C() : A(), B() 
  

  virtual void serialize() 
    // do my own serialize

    B::serialize(); // call B's serialize
  

  virtual void deserialize() 
    // do my own deserialize

    B::deserialize(); // call B's deserialize
  

  
  virtual void Bfunction() 
    // implement the interface
  

这行得通还是我的推理有问题?我想将序列化和反序列化委托给所有类实现,这样同一个基类就不会有不同的表示。

【问题讨论】:

如果类 C 继承自 B,为什么要另外继承自 A?它已经从 B 那里得到了它所需要的一切。 如果有的话,它是一种退化的菱形图案——对于那个你需要多一个类:D 继承自 C 和 B,而 C 和 B 都继承自 A。D 从 C 和另一个无法提供的B,因此您需要从两者继承,然后从C和B中获得一个单独的A。 【参考方案1】:

菱形继承“有问题”的原因在于,刚接触 C++ 的程序员尚未了解虚拟继承,因此不知道如何实现菱形。

您的遗产是那些试图继承钻石的人在他们不知道如何制作钻石时得到的结果。但是,您的遗产缺乏的是对钻石的明显需求。目前尚不清楚为什么您需要第二次继承 A 。如果你继承了 B,那么你间接继承了它的所有基础。我建议尝试以下方法:

class C : public B 

  virtual void serialize() 
      // do my own serialize
      B::serialize(); // call B's serialize
  

  virtual void deserialize() 
      // do my own deserialize
      B::deserialize(); // call B's deserialize
  

  
  virtual void Bfunction() 
    // implement the interface
  

【讨论】:

以上是关于我的继承和有问题的“钻石继承”一样吗的主要内容,如果未能解决你的问题,请参考以下文章

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

从多重/钻石继承继承

避免钻石继承[重复]

如何从钻石继承中的不同类别中获取值

C++菱形继承问题与虚拟继承原理

C++菱形继承问题与虚拟继承原理