c++virtual-inheritance

How can I inherit from two classes with the same non-virtual grandparent classes?


Suppose I have four classes A, B, C and D:

class A {
public:
    float someData;
    float someFunc();
}

class B : public A {
public:
    float someOtherData;
    float someOtherFunc();
}

class C : public A {
public:
    float evenMoreData;
    float evenMoreFuncs();
}

class D : public B, public C {
public:
    float andMoreData;
    float andMoreFuncs();
}

Now I want D to inherit only one instance of A. I know that this is diamond inheritance, which I could solve by adding a virtual to "public A" in B and C, but the problem here is that B and A belong to a library, which I can't change.

Is there any way to do this except from making B a member of D and wrapping all of B's member functions?

EDIT: As noted in the comments, in this case B would not need to inherit from A, but B also serves as a base class for other classes which by themself don't inherit any class that inherits A.


Solution

  • the problem here is that B and A belong to a library, which I can't change.

    Ok, so that leaves the only option to change C and D.

    You could make C into a class template which you can then use to either inherit from A or B - and in the case of D, you'll inherit from C<B> only:

    template<class Base>
    class C : public Base {
    public:
        float evenMoreData;
        float evenMoreFuncs();
    };
    
    class D : public C<B> {
    public:
        float andMoreData;
        float andMoreFuncs();
    };
    

    Demo


    Another option is to drop the inheritance and to use composition. Here C<A> will have an A member variable and C<B> will have a B member variable:

    template<class T>
    class C {
    public:
        T t;
        float evenMoreData;
        float evenMoreFuncs();
    };
    
    class D {
    public:
        C<B> c;
        float andMoreData;
        float andMoreFuncs();
    };
    

    Demo