So as part of the public API of my program I expose class D, such that the user inherits from class D to create their own classes.
However class D is the tip of the deadly diamond and I have run into an issue where the user's classes are calling the default constructor of class A, instead of the parametrized constructor as desired.
A
/ \
B C
\ /
D
|
E or F
In the following code, class E is a clean API however calls the wrong A constructor. Class F works as intended, however the user has to add A's parameterised constructor, which is ugly because that class is an internal class.
Is there a way to have class E work as intended? Why is this happening?
#include<iostream>
using namespace std;
class A {
public:
A(int x) { cout << "A::A(int ) called" << endl; }
A() { cout << "A::A() called" << endl; }
};
class B : virtual public A {
public:
B(int x): A(x) {
cout<<"B::B(int ) called"<< endl;
}
};
class C : virtual public A {
public:
C(int x): A(x) {
cout<<"C::C(int ) called"<< endl;
}
};
class D : public B, public C {
public:
D(int x): A(x), B(x), C(x) {
cout<<"D::D(int ) called"<< endl;
}
};
class E : public D {
public:
E(int x): D(x) {
cout<<"E::E(int ) called"<<endl;
}
};
class F : public D {
public:
F(int x): D(x), A(x) {
cout<<"F::F(int ) called"<<endl;
}
};
int main() {
D d(0);
cout<<endl;
E e(1);
cout<<endl;
F f(2);
}
Output:
A::A(int ) called
B::B(int ) called
C::C(int ) called
D::D(int ) called
A::A() called
B::B(int ) called
C::C(int ) called
D::D(int ) called
E::E(int ) called
A::A(int ) called
B::B(int ) called
C::C(int ) called
D::D(int ) called
F::F(int ) called
When constructing a class that has any virtual bases, initializers that name a virtual base class are only called for the most derived class. If your class has any virtual base classes, and you want to use the non-default constructor of that virtual base, then you must specify that constructor in the derived class.
1 " All virtual base subobjects are initialized before any non-virtual base subobject, so only the most derived class calls the constructors of the virtual bases in its member initializer list: ... "
2 " The initializers where class-or-identifier names a virtual base class are ignored during construction of any class that is not the most derived class of the object that's being constructed. "
This topic is relatively new to me, so I hope anybody with more experience will point out any nuance I missed.
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.