Можно ли использовать множественное наследование, если один родительский класс является интерфейсом?

Можно ли использовать множественное наследование, если один родительский класс является интерфейсом (содержит только чисто виртуальные функции с виртуальным деструктором)?

Я хочу выставить только интерфейсную часть (желтый класс на рисунке) для увеличения скорости компиляции. Зеленая часть - это часть реализации. Но 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()
Другие вопросы по тегам