C++ 虚拟基类的创建顺序
我有以下问题:C++ 虚拟基类的创建顺序,c++,constructor,multiple-inheritance,virtual-inheritance,order-of-execution,C++,Constructor,Multiple Inheritance,Virtual Inheritance,Order Of Execution,我有以下问题: struct A1 { A1() { std::cout << "A1, "; } }; struct A2 { A2() { std::cout << "A2, "; } }; struct AA1 : virtual A1, A2 { AA1() { std::cout << "AA1, "; } }; struct AA2 : A1, virtual A2 { AA2(){ std::cout &l
struct A1 {
A1() { std::cout << "A1, "; }
};
struct A2 {
A2() { std::cout << "A2, "; }
};
struct AA1 : virtual A1, A2 {
AA1() { std::cout << "AA1, "; }
};
struct AA2 : A1, virtual A2 {
AA2(){ std::cout << "AA2, "; }
};
struct B : AA1, virtual AA2 {
B() { std::cout << "B "; }
};
int main() {
B b;
}
结构A1{
A1(){std::cout第一个
A1
源于B
的(非虚拟)基AA1
的(虚拟)基的初始化
首先初始化
B
的所有虚拟基,它们依次是A1
、A2
和AA2
(初始化AA2
导致输出a1aa2
),然后是直接基,其中只有一个,AA1
(其初始化打印的是A2 AA1
),最后是类本身,打印B
。所有虚拟基类都排在第一位,然后只有剩余的非虚拟基类。B
有三个虚拟基类:A1
、A2
和AA2
,它将根据它们的出现顺序对它们进行初始化
您看到的第一个A1
和A2
是虚拟基A1
和A2
的初始化,但是最后一个虚拟基AA2
有一个非虚拟基A1
,因此在构建AA2
之前,您需要构建另一个A1
,这就是为什么您有另一个A1代码>在AA2
之前
您可以通过运行以下代码段将其可视化:
#include <iostream>
struct A1 {
A1(const char *s) { std::cout << "A1(" << s << ")\n"; }
};
struct A2 {
A2(const char *s) { std::cout << "A2(" << s << ")\n"; }
};
struct AA1 : virtual A1, A2 {
AA1(const char *s) : A1("AA1"), A2("AA1") { std::cout << "AA1(" << s << ")\n"; }
};
struct AA2 : A1, virtual A2 {
AA2(const char *s) : A1("AA2"), A2("AA2") { std::cout << "AA2(" << s << ")\n"; }
};
struct B : AA1, virtual AA2 {
B() : A1("B"), A2("B"), AA1("B"), AA2("B") { std::cout << "B()\n"; }
};
int main() {
B b;
}
您还可以注意到,此代码向您发出警告,因为:
- 我在
AA2
的构造函数中将A1
放在A2
之前,但是A2
将在A1
之前初始化(因为它是一个虚拟基,而A1
不是)
- 我在
B
的构造函数中将AA1
放在AA2
之前,但是AA2
将首先初始化(原因相同)
您能改进代码格式以便于阅读吗?虚拟类不会被“调用”。您不能“调用类”。相反,对象是初始化的。你是对的,我犯了一个错误。谢谢你的解释。非常感谢。这对我帮助很大。我一直在努力理解这个虚拟函数。它们是我唯一无法理解的,而这个答案对我帮助很大。第一个A1
实际上来自虚拟基从AA1
,而不是从AA2
(实际上是第二个A1
)的非虚拟基。您可以通过向构造函数添加一个参数来可视化这一点,该参数指示从何处“调用”。@DropFuriosPolaris:我最初的解释是错误的;由于霍尔特的更正,请查看更新的结果。
A1(B)
A2(B)
A1(AA2)
AA2(B)
A2(AA1)
AA1(B)
B()