Виртуальное наследование-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") {} };