在虚拟继承构造函数调用的顺序在虚拟继承构造函数调用的顺序(Order of constructor

2019-05-13 23:51发布

class A {
        int i;
public: 
        A() {cout<<"in A's def const\n";};
        A(int k) {cout<<"In A const\n";  i = k; }
        };

class B : virtual public A {
public:
        B(){cout<<"in B's def const\n";};
        B(int i) : A(i) {cout<<"in B const\n";}
        };

class C :   public B {
public:
        C() {cout<<"in C def cstr\n";}
        C(int i) : B(i) {cout<<"in C const\n";}
        };

int main()
{
        C c(2);
        return 0;
}

在这种情况下,输出是

in A's def const
in B const
in C const

这是为什么没有进入in A const

`应该遵循1个参构造函数调用的顺序。 然而,究竟什么是发生在从A使用虚拟关键字获得B中。

有几个问题

即使我删除上述程序的虚拟关键字,并删除所有默认的构造函数提示错误。 那么,为什么它需要的高清构造

Answer 1:

虚基类的构造函数总是从最派生类中调用,使用任何参数,可能传递。在你的情况下,最派生类没有指定一个初始化A ,因此使用默认的构造函数。



Answer 2:

作为JamesKanze解释 ,在的情况下, virtual继承是调用虚基类的构造函数最派生类。 所以,如果你想要A的构造函数的整数叫,你需要将它添加到C的初始化列表。

C(int i) : A(i), B(i) {cout<<"in C const\n";}

对于你的问题的第二部分,默认构造不是必需的,但随后的派生类必须显式调用非默认的构造函数,因为编译器是无法做到这一点你在没有非默认的构造函数。

#include <iostream>
using namespace std;

class A {
  int i;
public:
  // A() {cout<<"in A's def const\n";};
  A(int k) {cout<<"In A const\n";  i = k; }
};

class B : virtual public A {
public:
  // B(){cout<<"in B's def const\n";};
  B(int i) : A(i) {cout<<"in B const\n";}
};

class C :   public B {
public:
  C() : A(42), B(42) {cout<<"in C def cstr\n";}
  C(int i) : A(i), B(i) {cout<<"in C const\n";}
};

int main()
{
  C c(2), c2;
  return 0;
}

这种打印出

In A const
in B const
in C const
In A const
in B const
in C def cstr


Answer 3:

这里有两个问题。

这是为什么没有进入在一个const?

由于使用的是虚拟继承。

当你使用虚拟继承时, 最派生类的构造函数初始化列表中直接调用虚基类的构造函数。 。 在这种情况下,这意味着, C的构造函数调用A的构造直接 。 既然你没有指定哪A构造函数中调用C的初始化列表,默认构造函数被调用。

这是通过改变你的实现固定C::C(int)到:

C(int i) : A(i), B(i) {cout<<"in C const\n";}

如果删除上述程序的虚拟关键字,并删除所有默认的构造函数提示错误。 那么,为什么它需要的高清构造?

由于B也没有指定A构造函数调用,因此使用默认的构造函数。 如果你删除A小号高清男星, B不能编译。



文章来源: Order of constructor call in virtual inheritance