Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
248 views
in Technique[技术] by (71.8m points)

c++ - 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
");
}
SomeDerivedClass::SomeDerivedClass(int value) : SomeParentClass(value), SomeOtherParentClass(value) {
    printf("SomeDerivedClass(%d)
", 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()
"); }
  ~Base() {}
protected:
  Base(int value) { printf("Base(%d)
", value); }
};

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

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

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

Result:

Base()
Derived1(0)
Derived2()
question from:https://stackoverflow.com/questions/65644480/wrong-constructor-called-for-virtual-base-class-of-virtual-base-class

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...