使用虚拟继承时调用默认构造函数[重复]

Posted

技术标签:

【中文标题】使用虚拟继承时调用默认构造函数[重复]【英文标题】:Default constructor getting called while using virtual inheritance [duplicate] 【发布时间】:2013-09-25 06:40:15 【问题描述】:

在下面的代码中,当我创建 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 here\n";
;

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 C\n"; 
;

int main()

    C b(6);
    cout<<b.a;
    return 0;

【问题讨论】:

还有另一种选择来解释为什么调用它,直接关系到它是 Bvirtual 基,C 是从该基派生的。提示:B 的构造函数不是源,所以再考虑一下。 A(int z): a(z) cout 【参考方案1】:

这就是标准中对虚拟继承的描述。

[12.6.2] — 首先,并且仅针对最派生类 (1.8) 的构造函数,虚拟基类按照它们出现在有向无环的深度优先从左到右遍历的顺序进行初始化基类图,其中“从左到右”是派生类base-specifier-list中基类出现的顺序。

特别是,在构造C 时,A 子对象在其他任何东西(包括B 子对象)之前被初始化。由于A 不在有问题的C 构造函数的mem-initializers 列表中,因此使用A 的默认构造函数。

[12.6.2] — 然后,直接基类按照它们出现在 base-specifier-list 中的声明顺序进行初始化(不管 mem-initializers 的顺序如何)。 p>

然后构造B子对象。

[12.6.2] mem-initializer 其中 mem-initializer-id 表示虚拟基类在执行任何类的构造函数期间被忽略不是派生最多的类。

B的构造函数中的: A(z)在构造CB子对象时被忽略。

在日常语言中,这意味着您必须在每个直接或间接派生类中初始化一个虚拟基类,就好像它是一个直接派生类一样。如果您忘记这样做,则将强制使用默认构造函数,从而产生潜在的破坏性后果。 (这就是为什么你应该努力在任何虚拟基类中使用 only 默认构造函数或 no 默认构造函数。

【讨论】:

嗨,n.m,谢谢你这么详细的回答,现在我对这些事情很清楚了

以上是关于使用虚拟继承时调用默认构造函数[重复]的主要内容,如果未能解决你的问题,请参考以下文章

构造函数原型对象继承

虚拟继承、默认构造函数和额外复制

通过定义默认私有构造函数使类不可继承

关于类继承的构造与析构调用分析

从函数返回对象时调用C ++中的复制构造函数?

使用虚拟继承和委托构造函数在构造函数中崩溃