Виртуальное наследование-gcc против vc++
У меня есть проблема с 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;
}
Этот код прекрасно компилируется, если я использую gcc на своей машине linux. Но если я попытаюсь построить то же самое на windows с Visual Studio, компиляция завершится неудачей с сообщением об ошибке "error C2614: 'B': illegal member initialization: 'Print' не является базой или членом."
Почему это не работает?
2 ответа:
Из стандартного [класса.база.init]: "если mem-initializer-id не называет нестатический элемент данных класса конструктора или прямую или виртуальную базу этого класса, то mem-initializer неправильно сформирован."
Очевидно, gcc интерпретирует ваш случай как юридический, посколькуB, однако MSVC 2008 не видитB-только виртуальную базу невиртуальной базы. (Кстати, Ваш пример компилируется на VS2005, так что это удивительно изменение в поведении.)Я склоняюсь к интерпретации
gccКак правильной (в противном случае фраза "прямая основа" была бы достаточной).Чтобы обойти эту проблему, вы можете вывести
Bпрактически изA, это не оказывает никакого общего влияния на макет класса или количество подобъектов базового класса
Какую версию Visual Studio вы используете? Код, который вы опубликовали, прекрасно работает для меня с VC 9 (в частности, 15.00.21022.08) и VC 6, а также с несколькими другими компиляторами.
Вы уверены, что по ошибке
class Bне выглядит так в Visual Studio:class B { // note: no base class public: B () : Print("B") {} };