在下一个代码中,构建一个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;
}
答案 0 :(得分:2)
对于virtual
个基,最派生的类必须提供构造函数参数,例如:
struct C
: B1, B2 {
C()
: A(17)
, B2(3) {}
};
如果派生类最多的类没有在其初始化列表中提及virtual
库,则使用virtual
库的默认构造函数(如果没有,则表示错误)。
这样做的原因是为了避免歧义哪些派生类应该为共享virtual
基础提供构造函数参数:派生类最多的类最了解实际需要的内容。
答案 1 :(得分:0)
这正是编译器如何避免“死亡钻石”的原因。如果调用A(1)和A(2),意味着存在基类重复初始化,这是虚拟继承的目的 - 删除模糊的公共基本元素。