我有一个关于虚拟继承的Visual Studio 2008的问题. 请考虑以下示例: #includeiostreamclass Print { public: Print (const char * name) { std::cout name std::endl; }};class Base : public virtual Print { public: Base () : Prin
请考虑以下示例:
#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’不是基础或成员.”
为什么这不起作用?
从标准[class.base.init]:“除非mem-initializer-id命名构造函数类的非静态数据成员或该类的直接或虚拟基础,否则mem-initializer是不正确的.”很明显,gcc将您的案例解释为合法,因为Print是B的非直接但虚拟的基础,但是MSVC 2008并未将Print视为B的虚拟基础 – 只是非虚拟基础的虚拟基础. (顺便提一下,你的例子在VS2005上编译,所以这是一个令人惊讶的行为变化.)
我倾向于将gcc解释为正确(否则措辞’直接基础’就足够了).
要解决此问题,您可以从Print中虚拟地导出B.由于Print已经是A的虚拟基础,因此对类布局或基类Print子对象的数量没有任何整体影响.