Search code examples
c++constructordefault-constructorvirtual-inheritance

Virtual Inheritance: Interfaces and constructors


I am using C++11. I am trying to declare 2 interfaces: B and C, which each declare some functions to be implemented by the child classes. Both interfaces rely on variables and functions which are declared in the common A class. Even this relatively simple structure leads to the diamond heritance problem.(https://www.makeuseof.com/what-is-diamond-problem-in-cpp/) I use virtual inheritance to link A and B/C, trying to implement something like this:

#edit 1 Modified the original code snippet to be a minimal reproducable example.

class T1{};
class A{
public:
    A(const T1& param1);

    void myfuna();
    const T1 member1;
};
class B : public virtual A{
    virtual void myfunb()=0;
};
class C: public virtual A{
    virtual void myfunc()=0;
};
class Di: public B, public C{
    Di(const T1& param1): A(param1){}
    void myfunb() override;
    void myfunc() override;
};

However, this code won't compile. The reason is that cpp interfaces aren't exactly speaking "interfaces" (I have a Java background), as they still have a default constructor which is called, even when virtual inheritance is used. This means that upon initialization of an instance of "D", these constructors are called:

  • A(param1,param2)
  • B()
  • C()

The B and C constructors in turn try to call the A() constructor, which is ill-defined (I get the "call to implicitly-delete default constructor" error). The culprit is the const field of A, which disables the default constructor.

I can't find an elegant way to remedy this problem. Am I missing something, is my design flawed or is this just a limitation of cpp?


Solution

  • The solutions are:

    • Make B and C abstract classes.
    • Or define a default constructor for A.
    • Or call the non-default constructor of A in the constructors of B and C.