Diamond Problem C++:Derived class of diamond calls default constructor
Diamond Problem C++: Derived class of diamond calls default constructor
因此,作为我程序 public API 的一部分,我公开了 class D,以便用户继承 class D 来创建自己的 classes.
但是 class D 是致命钻石的尖端,我 运行 遇到用户的 class 正在调用 class 的默认构造函数的问题A,而不是根据需要的参数化构造函数。
A
/ \
B C
\ /
D
|
E or F
在下面的代码中,class E 是一个干净的 API 但是调用了错误的 A 构造函数。 Class F 按预期工作,但是用户必须添加 A 的参数化构造函数,这很丑陋,因为 class 是内部 class.
有没有办法让 class E 按预期工作?为什么会这样?
#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);
}
输出:
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
在构造具有任何虚基的 class 时,命名虚基 class 的初始值设定项仅被最派生的 class 调用。如果你的 class 有 any 虚拟基础 classes,并且你想使用那个虚拟基础的非默认构造函数,那么你必须在派生的 class.
1 "所有虚拟基子对象都在任何非虚拟基子对象之前初始化,因此只有最派生的 class 调用其成员中的虚拟基的构造函数初始值设定项列表:..."
2 " class-or-identifier 命名虚拟基 class 的初始值设定项在构造任何 class 期间被忽略不是正在构造的对象的最派生 class。"
这个话题对我来说比较新,所以我希望有更多经验的人指出我遗漏的任何细微差别。
因此,作为我程序 public API 的一部分,我公开了 class D,以便用户继承 class D 来创建自己的 classes.
但是 class D 是致命钻石的尖端,我 运行 遇到用户的 class 正在调用 class 的默认构造函数的问题A,而不是根据需要的参数化构造函数。
A
/ \
B C
\ /
D
|
E or F
在下面的代码中,class E 是一个干净的 API 但是调用了错误的 A 构造函数。 Class F 按预期工作,但是用户必须添加 A 的参数化构造函数,这很丑陋,因为 class 是内部 class.
有没有办法让 class E 按预期工作?为什么会这样?
#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);
}
输出:
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
在构造具有任何虚基的 class 时,命名虚基 class 的初始值设定项仅被最派生的 class 调用。如果你的 class 有 any 虚拟基础 classes,并且你想使用那个虚拟基础的非默认构造函数,那么你必须在派生的 class.
1 "所有虚拟基子对象都在任何非虚拟基子对象之前初始化,因此只有最派生的 class 调用其成员中的虚拟基的构造函数初始值设定项列表:..."
2 " class-or-identifier 命名虚拟基 class 的初始值设定项在构造任何 class 期间被忽略不是正在构造的对象的最派生 class。"
这个话题对我来说比较新,所以我希望有更多经验的人指出我遗漏的任何细微差别。