简体   繁体   中英

wrong constructor called for virtual base class of virtual base class

I'm having a problem with the constructors of a very complex class structure that is spread over several files. Each class has a public default contructor without arguments and a protected contructor with arguments. Each constructor of any derived class is calling the protected constructor of it's parent with arguments. The following example is the same for all derived classes in the structure (the number of parent classes may differ).

file example.h:

class SomeDerivedClass : virtual public SomeParentClass, virtual public SomeOtherParentClass {
public:
    SomeDerivedClass();
protected:
    SomeDerivedClass(int value);
}

file example.cpp:

SomeDerivedClass::SomeDerivedClass() : SomeParentClass(0), SomeOtherParentClass(0) {
    printf("SomeDerivedClass\n");
}
SomeDerivedClass::SomeDerivedClass(int value) : SomeParentClass(value), SomeOtherParentClass(value) {
    printf("SomeDerivedClass(%d)\n", value);
}

When I construct a class, all the direct virtual parents are constructed with the protected constructor that has arguments. But even though that protected construcor of the parents should also call the protected constructor of it's own virtual parents, the grandparents are always constructed with the default constructor.

Minimal example:

#include <stdio.h>

class Base {
public:
  Base() { printf("Base()\n"); }
  ~Base() {}
protected:
  Base(int value) { printf("Base(%d)\n", value); }
};

class Derived1 : virtual public Base {
public:
  Derived1() : Base(0) { printf("Derived1()\n"); }
  ~Derived1() {}
protected:
  Derived1(int value) : Base(value) { printf("Derived1(%d)\n", value); }
};

class Derived2 : virtual public Derived1 {
public:
  Derived2() : Derived1(0) { printf("Derived2()\n"); }
  ~Derived2() {}
protected:
  Derived2(int value) : Derived1(value) { printf("Derived2(%d)\n", value); }
};

int main() {
  Derived2* NewDerived2 = new Derived2();
}

Result:

Base()
Derived1(0)
Derived2()

The Answer is given in the comments by Sam Varshavchik.

The concept of passing the argument from each constructor to it's direct parent was the wrong way of handling the issue.

I was under the wrong impression, that I can only access the direct parents of each class. Sam Varshavchik's comment helped me to see the real problem and look for it in the right places. In one of the many classes, there was one non-virtual inheritance that made it impossible to access the constructor of the base class.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM