C虚拟继承初始化列表
作者:互联网
在以下代码中:
class A
{
public:
int x;
A(int x):x(x){}
};
class B: public virtual A
{
public:
B(int x):A(x){}
};
class C: public virtual A
{
public:
C(int x):A(x){}
};
class D: public B, public C
{
public:
D(int x):B(x++), C(x++), A(x++){}
};
两个问题:
>为什么我需要在D的初始化列表中添加A(…)?
> D(int x):B(x),C(x),A(x){}和D(int x):A(x),B(x),C(x){}都给出相同的结果与cout<< D(10).x,为什么?
解决方法:
Why do I need to add A(…) in D’s initializer list?
这是因为必须在所有其他子对象之前初始化虚拟基础子对象.由于A没有默认构造函数,因此需要在D中显式初始化虚拟A子对象,并指定要用它构造哪个参数.
当执行B和C基础子对象的构造函数时,它们将不具有要初始化的基础A子对象(已经在之前已经完成).因此,它们传递给A的构造函数的参数是无关紧要的.
D(int x):B(x++), C(x++), A(x++){}
andD(int x):A(x++), B(x++), C(x++){}
both give the same result withcout<<D(10).x
, why?
如上所述,这是因为无论如何首先初始化虚拟基础子对象.
通常,类的子对象的初始化顺序决不会取决于它们在构造函数的初始化列表中出现的顺序.根据C 11标准第12.6.2 / 10段:
In a non-delegating constructor, initialization proceeds in the following order:
— First, and only for the constructor of the most derived class (1.8), virtual base classes are initialized in
the order they appear on a depth-first left-to-right traversal of the directed acyclic graph of base classes,
where “left-to-right” is the order of appearance of the base classes in the derived class base-specifier-list.— Then, direct base classes are initialized in declaration order as they appear in the base-specifier-list
(regardless of the order of the mem-initializers).— Then, non-static data members are initialized in the order they were declared in the class definition
(again regardless of the order of the mem-initializers).— Finally, the compound-statement of the constructor body is executed.
标签:virtual-inheritance,c,constructor,inheritance,multiple-inheritance 来源: https://codeday.me/bug/20191008/1870392.html