4

I'm currently trying to wrap my head around the basics of C++ inheritance. Consider the following piece of code:

// Interfaces

class InterfaceBase
{
public:
    virtual void SomeMethod() = 0;
};

class InterfaceInherited : public InterfaceBase
{
};

// Classes

class ClassBase : public InterfaceBase
{
public:
    virtual void SomeMethod()
    {
    }
};

class ClassInherited : public ClassBase, public InterfaceInherited
{
};

int main()
{
    ClassBase myBase; // OK
    ClassInherited myInherited; // Error on this line

  return 0;
}

Here I have two interfaces with an inheritance relationship. The same goes for the two classes which implement the interfaces.

This gives me the following compiler error:

C2259 'ClassInherited': cannot instantiate abstract class

It seems that the class ClassInherited does not inherit the implementation of SomeMethod from ClassBase. Thus it is abstract and cannot be instantiated.

How would I need to modify this simple example in order to let ClassInherited inherit all the implemented methods from ClassBase?

Boris
  • 8,551
  • 25
  • 67
  • 120
  • In this case there's no need to inherit `ClassInherit` from `InterfaceInherited` _again_. It already inherits that interface from `ClassBase`. – Thomas Jan 04 '21 at 08:49
  • The fact is that it is inheriting from both `ClassBase` and from `InterfaceInherited`, but the last one has not defined the `SomeMethod` implementation, so that one is still pending in `ClassInherited`; this makes `ClassInherited` abstract so is not instatiable. – Edgar G. Jan 04 '21 at 09:03

1 Answers1

4

You are encountering a diamond problem. The solution is to use virtual inheritance (Live), to ensure that only one copy of base class members are inherited by grand-childs:

// Interfaces
class InterfaceBase
{
public:
    virtual void SomeMethod() = 0;
};

class InterfaceInherited : virtual public InterfaceBase
{
};

// Classes
class ClassBase : virtual public  InterfaceBase
{
public:
    virtual void SomeMethod()
    {
    }
};

class ClassInherited : public ClassBase, public InterfaceInherited
{
};

int main()
{
    ClassBase myBase; // OK
    ClassInherited myInherited; // OK
    return 0;
}
StPiere
  • 4,113
  • 15
  • 24
  • It would be good if you cleaned it up a little bit too. Increase indentation and remove some lines. There's no reason that this should require scrolling. See my edit of OP:s post. – klutt Jan 04 '21 at 08:57
  • 1
    Some compilers will [warn](https://godbolt.org/z/znEdEv) you about this inheritance structure. These warnings can be [ignored or silenced](https://stackoverflow.com/questions/6864550/c-inheritance-via-dominance-warning). – n. m. could be an AI Jan 04 '21 at 09:22