Search code examples
c++inheritancemultiple-inheritanceclass-design

Filling out abstract class members by deriving from concrete class


Let's say I have an interface that inherits from another interface (pure abstract class)

class BaseInterface
{};

Then another interface builds upon BaseInterface

class ExtendedInterface : public BaseInterface
{};

Now, I have a concrete class that implements BaseInterface:

class Base : public BaseInterface
{};

Now, I want to implement ExtendedInterface, but since I already have Base I want to fill out the BaseInterface members with base. E.g.:

class Extended : public ExtendedInterface, public Base
{};

This doesn't seem to work. I get complaints that I cannot instantiate extended since it is an abstract class. The only way I can get it to work is by using virtual inheritance, but then I get compiler warnings about inheriting via dominance.


Solution

  • What's the problem ?

    With your multiple inheritance, Extended inherits two times from BaseInterface. This means that there are two independent BaseInterface subobjects:

    • one is inherited via the concrete Base class, which has overridden all the pure virtual functions.

    • but the other is inherited via ExtendedInterface class, which is still abstract.

    enter image description here

    In consequence, as some subobjects of Extended still have pure virtual functions, your class is still an abstract class that can't be instantiated.

    How to solve it ?

    As despite the multiple inheritance you apparently expect to have only one BaseInterface, you need to use virtual inheritance:

    class BaseInterface                                       
    { virtual void test()=0; };                              // abstract class
    
    class ExtendedInterface : public virtual BaseInterface   // virtual inheritance
    {};                                                      // abstract class
    
    class Base : public virtual BaseInterface                // virtual inheritance
    { void test() override {} };                             // concrete class
    
    class Extended : public ExtendedInterface, public Base   // multiple 
    {};                             // thanks to virtual inheritance, concerete class 
    

    With this logic, there will be only one BaseInterface in Extended, with virtual functions overridden, and you can instantiate it.

    Here an online demo