虚拟继承 - gcc与vc ++

时间:2009-09-17 07:13:51

标签: c++ gcc visual-c++ virtual-inheritance

我的Visual Studio 2008存在与虚拟继承有关的问题。

考虑以下示例:

#include<iostream>

class Print {
    public:

    Print (const char * name) {
        std::cout << name << std::endl;
    }
};

class Base : public virtual Print {
    public:

    Base () : Print("Base") {}
};

class A : public Base {
    public:

    A () : Print("A") {}
};

class B : public A {
    public:

    B () : Print("B") {}
};

int main (int argc, char** argv) {
    A a; // should print "A"
    B b; // should print "B"
    return 0;
}

如果我在linux机器上使用gcc,这段代码编译得很好。 但是,如果我尝试使用Visual Studio在Windows上构建相同的内容,则编译将失败,并显示错误消息“错误C2614:'B':非法成员初始化:'Print'不是基础或成员。”

为什么这不起作用?

2 个答案:

答案 0 :(得分:4)

从标准[class.base.init]:“除非mem-initializer-id命名构造函数类的非静态数据成员或该类的直接或虚拟基础,否则mem-initializer是不正确的。 “

显然,gcc会将您的案例解释为合法,因为PrintB的非直接但虚拟的基础,但MSVC 2008并未将Print视为B的虚拟基础{1}} - 只是非虚拟基础的虚拟基础。 (顺便提一下,你的例子是在VS2005上编译的,所以这是一个令人惊讶的行为改变。)

我倾向于将gcc解释为正确(否则措辞'直接基础'就足够了。)

要解决此问题,您可以从B虚拟派生Print。由于Print已经是A的虚拟基础,因此对类布局或基类Print子对象的数量没有任何整体影响。

答案 1 :(得分:0)

您使用的是哪个版本的Visual Studio?您发布的代码适用于VC 9(特别是15.00.21022.08),VC 6以及其他一些编译器。

您确定错误class B在Visual Studio中看起来不像这样:

class B {  //  note: no base class
    public:

    B () : Print("B") {}
};