Search code examples
c++multiple-inheritancediamond-problem

Is my inheritance the same as the problematic "diamond inheritance"


I have multiple virtual base classes that create interfaces for my implementation classes. I however want them all to be able to serialize and deserialize themselves. This resultes in the following ABC inheritance:

Lets say I have class A which allows for serialisation and deserialisation of the class.

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

I have a class B which adds some virtual calls but must also be able to handle it's own serialization operations:

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;
}

Now I have a class C which implements both functionality from A and B. In the pattern of:

 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
  }

Will this work or is there something wrong in my reasoning? I want to delegate the serialization and deserialization to all class implementations so there won't be different representations for the same base class.


Solution

  • What makes diamond inheritance "problematic" is that programmers new to C++ haven't yet learned about virtual inheritance and thus don't know how to achieve the diamond.

    Your inheritance is what people attempting the diamond inheritance end up with when they don't know how to make the diamond. However, what your inheritance lacks is the apparent need for the diamond. It's unclear why you need to inherit A a second time. If you inherit B, then you indirectly have inherited all its bases. I recommend trying out following instead:

    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
      }