Можно ли использовать множественное наследование, если один родительский класс является интерфейсом?
Можно ли использовать множественное наследование, если один родительский класс является интерфейсом (содержит только чисто виртуальные функции с виртуальным деструктором)?
Я хочу выставить только интерфейсную часть (желтый класс на рисунке) для увеличения скорости компиляции. Зеленая часть - это часть реализации. Но CPet должен наследовать от CAnimal(is-a отношение) и IPet(реализовать), есть "Diamond of Death":(
Интерфейсные классы (желтым цветом) имеют только чисто виртуальные функции и виртуальное уничтожение, поэтому, когда я создаю CDog, CCat через фабричный класс, не возникает таких проблем, как двусмысленность. CDog имеет две vtables (из IDog и CPet), но в таблицах виртуальных функций точки указывают одну и ту же функцию (функции-члены CDog).
Нет ошибки компиляции, нет ошибки запуска... но я беспокоюсь об этой иерархии. Это нормально или есть проблемы?
PS: я не хочу использовать "виртуальное наследование", потому что, если я его использую, я не могу заглянуть в переменную члена класса через представление просмотра (я думаю, это потому, что ссылка виртуального наследования на родительский класс похожа на связанный список).
Среда: Visual Studio C++ 2008 или более поздняя.
1 ответ
Учитывая приведенное выше описание, вы не сможете создать экземпляр CPet
потому что чисто виртуальная функция IAnimal::isAlive()
не определено в IPet
виртуальные таблицы.
struct IAnimal {
virtual ~IAnimal() {}
virtual void isAlive() = 0;
};
struct IPet : public IAnimal {
};
struct CAnimal : public IAnimal {
virtual void isAlive() {
}
};
struct CPet : public CAnimal, public IPet {
};
int main(void) {
CPet cp;
}
Производит следующее при компиляции с Visual C++ 2008 и 2010:
animal.cpp(18) : error C2259: 'CPet' : cannot instantiate abstract class
due to following members:
'void IAnimal::isAlive(void)' : is abstract
mytest.cpp(5) : see declaration of 'IAnimal::isAlive'
GCC выдает похожее предупреждение:
animal.cpp: In function 'int main()':
animal.cpp:18:7: error: cannot declare variable 'cp' to be of abstract type 'CPet'
animal.cpp:14:8: note: because the following virtual functions are pure within 'CPet':
animal.cpp:3:15: note: virtual void IAnimal::isAlive()