C ++初始化列表忽略调用父类构造函数

时间:2013-10-05 15:13:24

标签: c++ inheritance initialization-list

在下一个代码中,构建一个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;
}

2 个答案:

答案 0 :(得分:2)

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

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

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

这样做的原因是为了避免歧义哪些派生类应该为共享virtual基础提供构造函数参数:派生类最多的类最了解实际需要的内容。

答案 1 :(得分:0)

这正是编译器如何避免“死亡钻石”的原因。如果调用A(1)和A(2),意味着存在基类重复初始化,这是虚拟继承的目的 - 删除模糊的公共基本元素。