c ++中的虚拟继承被误解了

use*_*165 1 c++ inheritance virtual-inheritance

我读到在虚拟继承中,构造函数被称为"从最派生的".请考虑以下代码.在我看来,这里派生最多的类是D.然后B和C和"最不得派"是A.那么为什么最先调用"Base"构造函数而不是"派生最多"?谢谢.

#include <iostream>
using namespace std;

struct A
{
    A()
    {
        cout << "A default constructor" << endl;
    }
};

struct B : virtual public A
{
    B() : A()
    {
        cout << "B default constructor" << endl;
    }
};

struct C : virtual public A
{
    C() : A()
    {
        cout << "C default constructor" << endl;
    }
};

struct D : public B, public C
{
    D() : B(), C()
    {
        cout << "D default constructor" << endl;
    }
};

int main()
{
    D d;
}
Run Code Online (Sandbox Code Playgroud)

这是输出:

A default constructor
B default constructor
C default constructor
D default constructor
Run Code Online (Sandbox Code Playgroud)

更新:


好.所以请考虑以下代码.请注意,虽然D,B和C构造函数发送了7,但是打印了10个.实际上,基类第一个被调用的类.没有从D到B到A的链.首先调用A()(实际上它是默认构造函数).然后才调用B和C构造函数.

但我读到:"从最衍生的." 来源:c ++虚拟继承

这里得到的最多的是D然后是B和C,然后只有A.那么为什么A首先被调用而不考虑参数B,D,C从它们的构造函数转移到它?谢谢.

代码 :

#include <iostream>
using namespace std;

struct A
{
    int _x;
    A()
    {
        _x = 10;
        cout << "A default constructor" << endl;
    }
    A(int x)
    {
        _x = x;
        cout << "A NOT-default constructor" << endl;
    }
};

struct B : virtual public A
{
    B(int x=7) : A(x)
    {
        cout << "B  constructor" << endl;
    }
};

struct C : virtual public A
{
    C(int x=7) : A(x)
    {
        cout << "C  constructor" << endl;
    }
};

struct D : public B, public C
{
    D(int x=7) : B(x), C(x)
    {
        cout << "D  constructor" << endl;
    }
};

int main()
{
    D d;
    cout << d._x;
}
Run Code Online (Sandbox Code Playgroud)

输出 :

A default constructor
B  constructor
C  constructor
D  constructor
10
Run Code Online (Sandbox Code Playgroud)

Ded*_*tor 5

在C++中构造顺序非常简单:

  1. 你叫一个最衍生的ctor(通过初始化的变量; 自动存储类,static的,动态的,等等).
  2. 该ctor初始化所有子对象:
    • 委托代理人调用另一个派生最多的代理人.
    • 非委派代理人自己完成工作:
      1. Iff是派生最多的ctor,virtual以左第一个声明顺序为基础.(这意味着忽略非最大派生者给出的虚拟基础ctor的参数)
      2. 左前一个声明顺序中的其他直接基础.
      3. 声明顺序中的成员.
  3. ctors身体运行.

由于你最基础的ctor是唯一的虚拟基地,它的主体是第一个运行的主体,由最派生的ctor直接调用.

在一般情况下,呼叫virtual功能,typeid并且dynamic_cast是安全的,但都被初始化基子对象不前:我可以调用虚函数初始化基类的子对象?