3

Let's say I've got the following class hierarchy, wherein I have an interface and then further specializations of that interface that guarantee more functionality:

class parent_interface {
 public:
  virtual void foo() = 0;
};

class child1_interface : public parent_interface {
 public:
  virtual void bar() = 0;
};

class child2_interface : public parent_interface {
 public:
  virtual void baz() = 0;
}

And then I have concrete classes that provide that functionality:

class parent : public parent_interface {
 public:
  void foo() override;
};

class child1 : public parent, public child1_interface {
 public:
  //using parent::foo; ??
  void bar() override;
};

The problem is if I try to instantiate a child1 object, I get a compiler error that

cannot declare field instantiation_name to be of abstract type because the following virtual functions are pure within child1: void foo()

I can fix this by creating a method within child1 called foo, that just calls parent::foo, but I'm wondering if there is a cleaner solution to this problem.

Alan Birtles
  • 32,622
  • 4
  • 31
  • 60
sheridp
  • 1,386
  • 1
  • 11
  • 24
  • You have a *diamond inheritance pattern*. If you search for e.g. `c++ diamond inheritance pattern` you should get plenty of hits about the problem with it, and possible solutions. – Some programmer dude May 14 '19 at 18:19

1 Answers1

1

You need to specify virtual inheritance, so that the compiler knows to combine the base classes back into one. This should compile for you (see it work):

class parent_interface {
 public:
  virtual void foo() = 0;
};

class child1_interface : public virtual parent_interface {
 public:
  virtual void bar() = 0;
};

class parent : public virtual parent_interface {
 public:
  void foo() override
  {
  }
};

class child1 : public parent, public child1_interface {
 public:
  //using parent::foo; ??
  void bar() override
  {
  }
};

For more information, you can read about Virtual Base Classes here.

Darrin Cullop
  • 1,170
  • 8
  • 14
  • Ah, I had tried making child1_interface and child2_interface inherit parent_interface virtually, but I did not think to make parent virtually inherit from parent_interface. Also, I don't think it is necessary to have child1 inherit virtually from parent and child1_interface. Regular inheritance works fine. – sheridp May 14 '19 at 18:30
  • You are correct about that. You only need to specify `virtual` just before deriving from the interface. I updated the code in my answer to reflect this. – Darrin Cullop May 14 '19 at 18:38