使用虚拟继承时调用默认构造函数
Default constructor getting called while using virtual inheritance
在下面的代码中,当我创建 C 的对象时,A'a 默认构造函数通过 B 的构造函数被调用,为什么会这样?
#include <iostream>
using namespace std;
class A
{
public:
int a;
A(int z): a(z) {cout<<"a is "<<a;}
A() { cout<<" it came heren";}
};
class B: public virtual A
{
public:
B(int z): A(z) {cout<<"in B and z is "<<z<<"n"; }
};
class C:public B
{
public:
C(int z): B(z) {cout<<" In Cn"; }
};
int main()
{
C b(6);
cout<<b.a;
return 0;
}
这就是标准中描述虚拟继承的方式。
[12.6.2] — 首先,并且仅对于派生最多的类 (1.8( 的构造函数,虚拟基类按照它们在基类的有向无环图的深度优先从左到右遍历上的顺序进行初始化,其中"从左到右"是基类在派生类基说明符列表中的出现顺序。
特别是,在构造C
时,A
子对象先于其他任何对象(包括B
子对象(进行初始化。由于A
不在违规C
构造函数的mem-initializers
列表中,因此使用 A
的默认构造函数。
[12.6.2] — 然后,直接基类按照它们出现在基说明符列表中的声明顺序进行初始化(无论 mem 初始值设定项的顺序如何(。
然后构造B
子对象。
构造[12.6.2] 一个 mem 初始值设定项,其中 mem-initializer-id 表示虚拟基类,在执行不是派生最多的类的任何类的构造函数时被忽略。
B
的构造函数中的: A(z)
在构造 C
的B
子对象时被忽略。
在日常语言中,这意味着您必须在每个直接或间接派生类中初始化一个虚拟基类,就好像它是直接派生类一样。如果您忘记这样做,将强制使用默认构造函数,并可能带来毁灭性的后果。(这就是为什么您应该努力在任何虚拟基类中仅使用默认构造函数或根本没有默认构造函数的原因(。
相关文章:
- 如何在C++中调用默认模板功能参数?
- 为什么即使我调用参数化构造函数也会调用默认构造函数?
- 没有用于调用默认构造函数的匹配函数
- 为什么指针对象没有调用默认构造函数
- 调用默认构造函数时不引用它
- 为什么我的对象声明不调用默认构造函数?
- 为什么要尝试调用默认构造函数?
- 在创建对象向量时,不为每个对象唯一调用默认对象构造函数
- std::map 在 [] 上调用默认构造函数,在 insert() 上调用复制构造函数
- 是否可以从移动构造函数调用默认构造函数?
- 为什么类型变量;不调用默认 CTR
- 声明对象而不调用默认构造函数
- 作为参数的空初始值设定项列表不调用默认构造函数
- 如果类划分为单独的文件,则不调用默认构造函数
- 为什么"S x({})"仅在GCC 7/C++1z模式下调用默认构造函数?
- C++ 继承基构造函数,但仍调用默认派生构造函数
- 在返回语句中调用默认构造函数
- 在构造函数参数中调用默认构造函数
- 如何防止在基类初始化器中调用默认构造函数?
- 如何在以下C 代码中在同一对象上调用默认值和复制构造函数