代码之家  ›  专栏  ›  技术社区  ›  swegi

虚拟继承-GCC与VC++

  •  4
  • swegi  · 技术社区  · 15 年前

    我对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上构建它,编译将失败,并显示错误消息“error c2614:'b”:非法的成员初始化:“print”不是基或成员。

    为什么这不起作用?

    2 回复  |  直到 12 年前
        1
  •  4
  •   CB Bailey    12 年前

    从标准的[class.base.init]:“除非mem initializer id指定构造函数类的非静态数据成员或该类的直接或虚拟基,否则mem initializer格式错误。”

    显然,GCC将您的案件解释为 Print 是一个非直接但虚拟的基础 B 但是,MSVC 2008没有看到 打印 作为 B -只有非虚拟基的虚拟基。(顺便说一下,您的示例是在VS2005上编译的,所以它的行为发生了令人惊讶的变化。)

    我倾向于 gcc 解释是正确的(否则用“直接基础”这个词就足够了)。

    为了解决这个问题,你可以得出 实际上来自 打印 . AS 打印 已经是的虚拟基础 A 这对类布局或基类数量没有任何总体影响 打印 子对象。

        2
  •  0
  •   Michael Burr    15 年前

    您使用的是什么版本的Visual Studio?您发布的代码对我来说非常适用于VC 9(特别是15.00.21022.08)、VC 6以及其他一些编译器。

    你确定是错的吗 class B 在Visual Studio中不像这样:

    class B {  //  note: no base class
        public:
    
        B () : Print("B") {}
    };