2

The Child constructor in the code below calls its parent constructor to initialise itself. However the code won't compile unless Child also calls the Grandparent constructor, even though this is an implementation detail that's supposed to be hidden within Parent. I don't want to expose this detail to users of the Child class, as it may change in future. How can I get the code below working?

I tried changing the inheritance to 'private', but the Child constructor was still expected to know about this private arrangement, which IMHO somewhat defeats the purpose of private inheritance!

Any suggestions?

#include <iostream>

class MyObject {
  public:
    MyObject(int i) {
      std::cout << "MyObject(" << i << ") constructor" << std::endl;
    }
};

class Grandparent {
  public:
    Grandparent(MyObject i)
    {
    };
};

class Parent: virtual public Grandparent {
  public:
    Parent(int j) :
      Grandparent(MyObject(j))
    {
    };
};

class Child: virtual public Parent {
  public:
    Child() :
      //Grandparent(MyObject(123)),  // Won't work without this
      Parent(5)
    {
    };
};

int main(void)
{
  Child c;
  return 0;
}
$ g++ -o test test.cpp
test.cpp: In constructor ‘Child::Child()’:
test.cpp:29: error: no matching function for call to ‘Grandparent::Grandparent()’
test.cpp:12: note: candidates are: Grandparent::Grandparent(MyObject)
test.cpp:10: note:                 Grandparent::Grandparent(const Grandparent&)
Malvineous
  • 25,144
  • 16
  • 116
  • 151
  • possible duplicate of [gcc c++ virtual inheritance problem](http://stackoverflow.com/questions/2126522/gcc-c-virtual-inheritance-problem) – CB Bailey Dec 19 '10 at 10:58

2 Answers2

5

It's because the inheritance is virtual. Virtual inheritance can never be an implementation detail because the Child class has to manage the instances of any multiply-inherited class. If you use normal inheritance then this should not be a problem.

Puppy
  • 144,682
  • 38
  • 256
  • 465
  • That does appear to be the problem - thanks! Any pointers/reasoning as to why this is the case?? – Malvineous Dec 19 '10 at 10:53
  • 1
    @Malvineous, [This article](http://www.learncpp.com/cpp-tutorial/118-virtual-base-classes/) is the best explanation I managed to find. Basically it is to ensure that even in case of multiple inheritance the virtual base constructor will be called only once (by the most derived class, out of normal constructor chain). – Sergei Tachenov Dec 19 '10 at 11:15
1

It works fine for me when the virtual inheritance is removed.

Johan Kotlinski
  • 25,185
  • 9
  • 78
  • 101