了解虚拟基类和构造函数调用

pyt*_*hor 13 c++ virtual multiple-inheritance base-class

我对虚拟基类的工作原理有点困惑.特别是,我想知道如何调用基类的构造函数.我写了一个例子来理解它:

#include <cstdio>
#include <string>
using std::string;

struct A{
    string s;
    A() {}
    A(string t): s(t) {}
};

struct B: virtual public A{
    B(): A("B"){}
};

struct C: virtual public A {};

struct D: public B, public C {};

struct E: public C, public B {};

struct F: public B {};

int main(){
    D d;
    printf("\"%s\"\n",d.s.c_str());
    E e;
    printf("\"%s\"\n",e.s.c_str());
    F f;
    printf("\"%s\"\n",f.s.c_str());
    B b;
    printf("\"%s\"\n",b.s.c_str());
}
Run Code Online (Sandbox Code Playgroud)

哪个输出

""
""
""
"B"
Run Code Online (Sandbox Code Playgroud)

我不确定前两种情况会发生什么,但对于第三种情况,我至少期待输出为"B".所以现在我只是感到困惑.理解A的构造函数如何被调用的规则是什么?

Ker*_* SB 9

始终只有一个构造函数调用,并且始终是您实例化的实际的具体类.这是你的责任,赋予每个派生类与调用基类的构造函数必要时并构造,像你一样在B类的构造函数.

更新:很抱歉错过了你的要点!感谢ildjarn.

但是,你实际上是从中B继承的.根据标准(FIDS中的10.1.4),"对于指定为virtual的每个不同的基类,最派生的对象应包含该类型的单个基类子对象".在你的情况下,这意味着在构造基类时,你的类会立即调用默认构造函数,而不是.AFAB


Pup*_*ppy 7

虚基类总是由派生类最多的类构成.

  • @Tomalak:它确实解释了展示的行为,因为`C`,`D`,`E`和`F`负责初始化他们的`A`子对象,而没有做到; 因此,他们的"A"子对象总是默认构造,尽管后者3的红色鲱鱼继承自"B". (4认同)
  • @Tomalak:是的,它不直观.: - ]虚拟继承的语义是Java和C#中不允许多重继承的主要原因之一. (3认同)