Search code examples
c++multiple-inheritancediamond-problem

Memory allocation for multiple inheritance with non-default constructors


I'm struggling a bit to understand multiple-inheritance. Apparently I chose to solve a very complicated problem that has multiple inheritance and also the diamond problem. Even if I I have found a couple of cases that are similar to my problem, for example this one, my question is is on memory more than order of execution.

Suppose I have the following:

class Matrix {
public:
  Matrix(int rows, int Cols) {
    // Build matrix of zeros
  }
};

class Symmetric : public virtual Matrix {
public:
  // It's enough to call Matrix constructor using the same number of rows and cols
  Symmetric(int size) : Matrix(size, size) {}
};

class PosDef : public virtual Matrix {
public:
  // We need different constructor, matrix of zeros is not pos def
  PosDef(int size) {
    // Build matrix of ones
  }
};

class SymmPosDef : public Symmetric, public PosDef {
public:
  // We basically want to use the PosDef constructor that gives symmetric matrix
  SymmPosDef(int size) : Matrix(size, size), Symmetric(size), PosDef(size) {}
};

Because I have given non-default constructors the only way to initialise a SymmPosDef object is with the complicated chain SymmPosDef(int size) : Matrix(size, size), Symmetric(size), PosDef(size) {} and my question is how many matrices am I building?

Am I allocating space once for Matrix, once for Symmetric (which would be the same zero elements) and once for PosDef or am I reusing the same space?

Because the size of the matrices could be large I want to do the least possible work.


Solution

  • Matrix is initialized (from initalizer list) only once, in the most derived class. But all constructor body will be called.

    With:

    class SymmPosDef : public Symmetric, public PosDef {
    public:
      SymmPosDef(int size) : Matrix(size, size), Symmetric(size), PosDef(size) {}
    };
    

    You would have:

    • Matrix(size, size)
    • (Symmetric(int size) : Matrix(size, size) skipped)
    • Symmetric(int size) body (/*Empty*/).
    • (PosDef(int size) : Matrix(size, size) skipped)
    • PosDef(int size) body ( /* Build matrix of ones */ )
    • SymmPosDef(int size) body (/*Empty*/).