虚拟基类的创建顺序
Virtual base classes order of creation
我有以下问题:
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 A2 A1 AA2A2 AA1 B
我想了解第一个A1
在哪里创建。
我知道在非虚拟类之前调用虚拟类的规则,但第一个 A1 是困扰我的问题。
第一个A1
是由B
的(非虚拟)基AA1
的(虚拟)基的初始化产生的。
B
的所有虚基首先初始化,它们依次是A1
、A2
和AA2
。(AA2
的初始化会导致输出A1 AA2
。然后是直接基,其中只有一个,AA1
(其初始化打印A2 AA1
),最后是类本身,打印B
。首先是所有虚拟基础,然后只有其余的非虚拟基础。
>B
有三个虚拟基类:A1
、A2
和AA2
,根据它们的出现顺序,它将按这个顺序初始化它们。
你看到的第一个A1
和A2
是虚拟基A1
和A2
的初始化,但是最后一个虚拟基AA2
有一个非虚拟的基A1
,所以在构造AA2
之前,你需要构造另一个A1
,这就是为什么在AA2
之前你还有另一个A1
。
可以通过运行以下代码片段来可视化这一点:
#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;
}
这将输出:
A1(B)
A2(B)
A1(AA2)
AA2(B)
A2(AA1)
AA1(B)
B()
您还可以注意到此代码会发出警告,因为:
- 我在
AA2
的构造函数中A2
之前放了A1
,但A2
将在A1
之前初始化(因为它是一个虚拟基,而A1
不是)。 - 我在
B
的构造函数中AA2
之前放了AA1
,但AA2
将首先初始化(同样的原因)。
相关文章:
- C++从其他 constexpr 创建 lambda 不能按顺序执行 Constexpr
- 具有包含其他对象的类的对象创建顺序
- 如何创建线程序列以按照启动顺序执行任务?
- 如何创建跟踪以显示存在递归的调用顺序
- 我不知道如何创建一个以数字/字母顺序打印出我的整数或字符串的程序
- 创建按顺序索引的有序映射
- 虚拟基类的创建顺序
- 替换decorator模式以强制执行创建顺序
- 按执行顺序创建Pthread
- 创建顺序类对象
- 在同一优先级队列中创建递增和递减顺序选项
- C++和QML的对象顺序创建QT
- 对象创建和销毁顺序(按C++排列)
- 使用一个数组以相反的顺序创建另一个数组
- 原始数据包创建导致 IP 字段顺序不正确
- 为具有默认值的非顺序参数函数创建启动器
- 如何设置在运行时创建的Windows控件之间移动的顺序
- 我正在创建一个双链接列表,它将按字母顺序排列姓名列表,但我不确定在int main()函数中放入什么
- 从相同的结构体以相反的顺序创建两个优先级队列
- 在visual c++中以递增的顺序创建数据文件