虚拟继承基构造函数消除

virtual inheritance base constructor elimination

本文关键字:构造函数 继承 虚拟      更新时间:2023-10-16
struct A3 {
int x;
A3(int x_): x(x_) {cout << "A3: " << x_  << endl;}
};
struct B3: virtual public A3 {
B3(int x_): A3(x_) {cout << "B3: " << x_  << endl;}
};
struct C3: virtual public A3 {
C3(int x_): A3(x_) {cout << "C3: " << x_  << endl;}
};
struct D3: B3, C3 {
D3(int x_): A3(x_), B3(x_), C3(x_) {cout << "D3: " << x_  << endl;}
};

对于上面的代码:输出为 A3、B3、C3、D3。编译器似乎消除了 B3 和 C3 中对 A3 的调用。 消除是如何工作的? 这是否意味着我们只能从 D3 调用 A3 的构造函数?

消除是如何工作的?

这是一个实现细节,但这通常是由编译器为一个类型发出两个不同的构造函数来完成的。当类型是基类时,一个构造函数用于类型,另一个构造函数用于派生最多的对象类型。

当存在虚拟基时,c'tor 的基类版本不包含对虚拟 c'tor 的调用。虽然 c'tor 的最派生对象版本确实包含对虚拟基地的 c'tor 的调用。

由于编译器知道在什么上下文中使用类型,因此它可以选择要调用的适当 c'tor。

这是否意味着我们只能从 D3 调用 A3 的构造函数?

我们只能从派生最多的对象类型中调用它。如果该类型是D3,则这是唯一将调用A3的 c'tor。

实际上在这种情况下只创建了一个 A3 实例,所以是的,我们只能从 D3 调用 A3 的构造函数,但在后台,编译器可以以任何方便的方式执行它。