Home > database >  Inheritance mess with pure virtual functions, any way to not have to re-define them all?
Inheritance mess with pure virtual functions, any way to not have to re-define them all?

Time:09-18

So I found myself in a bit of a mess of a class hierarchy.

I have code that looks a bit like that, oversimplified:

#include <iostream>

struct Parent {
  virtual void pureVirtual() = 0;
};

struct Child : public Parent {
  void pureVirtual() override {
    std::cout << "Child::pureVirtual()" << std::endl;
  }
};

struct Brother: public Parent {
};

struct GrandChild : public Child, public Brother {
};

GrandChild test;

The compilation fails with:

object of abstract class type "GrandChild" is not allowed: -- pure virtual function "Parent::pureVirtual" has no overriderC/C (322)

I don't fully understand why the implementation of pureVirtual is not inherited by GrandChild from Child.

In practice, I have tons of pure-virtual functions to "re-implement", that is, just writing lines like:

struct GrandChild : public Child, public Brother {
  void pureVirtual() override {
    Child::pureVirtual();
  }
};

I would have expected the compilator to automatically use the implementation from Child.

Is there any sort of trick I can use to tell the compiler that I am gonna re-use all the implementations from Child?

Anyway I probably have to think of a better design, but this got me interested if there are easy solutions.

CodePudding user response:

The issue is that you actually are getting two pureVirtual functions. C isn't smart enough to merge the two by default. You can use virtual inheritance to force the behavior.

#include <iostream>

struct Parent {
  virtual void pureVirtual() = 0;
};

struct Child : virtual public Parent {
  void pureVirtual() override {
    std::cout << "Child::pureVirtual()" << std::endl;
  }
};

struct Brother : virtual public Parent {};

struct GrandChild : public Child, public Brother {};

int main() {
  GrandChild test;
}

CodePudding user response:

I don't fully understand why the implementation of pureVirtual is not inherited by GrandChild from Child.

Actually, GrandChild does inherit the override implementation of pureVirtual() in Child.

But, GrandChild also inherits pureVirtual() from Brother. Brother is abstract since it does not override its version of pureVirtual(), hence GrandChild is also abstract unless it provides an override for Brother::pureVirtual() as well.

You have a classic Diamond hierarchy. You need to use virtual inheritance to solve it.

How does virtual inheritance solve the "diamond" (multiple inheritance) ambiguity?

Solving the Diamond Problem with Virtual Inheritance

  • Related