0

在接下来的代码中,构建一个 C 类首先初始化 A,然后是 B1,然后是 B2,最后是 C 类。但是,在初始化 B1 和 B2 时,调试器忽略了 A(1) 和 A(2) 的初始化(按此顺序出现在 B1 和 B2 的初始化列表中),但没有忽略 B2(3) 的初始化在 C 初始化列表中。

这是为什么?

提前致谢。

这是代码:

struct A { 
    int i; 
    A() { i = 0; } 
    A(int _i) : i(_i) {} 
    virtual void f() { cout << i; } 
}; 

struct B1 : virtual A { 
    B1() : A(1) { f(); } 
    void f() { cout << i+10; } 
}; 

struct B2 : virtual A { 
    B2(int i) : A(2) { f(); } 
}; 

struct C : B1, B2 { 
    C() : B2(3) {} 
};

int _tmain(int argc, _TCHAR* argv[])
{
    C* c = new C();
    return 0;
}
4

2 回答 2

2

对于virtual基类,派生最多的类必须提供构造函数参数,例如:

struct C
    : B1, B2 { 
    C()
        : A(17)
        , B2(3) {} 
};

如果最派生类在其初始化列表中没有提及virtual基类,则使用基类的默认构造函数virtual(如果没有,则为错误)。

这样做的原因是为了避免哪个派生类应该为共享virtual基类提供构造函数参数的歧义:最派生类最清楚实际需要什么。

于 2013-10-05T15:29:51.107 回答
0

这正是编译器避免“死亡钻石”的方式。如果 A(1) 和 A(2) 会被调用,意味着有基类重复初始化,这就是虚拟继承的目的 - 删除模棱两可的公共基础元素。

于 2013-10-05T15:58:08.580 回答