Вызов чистой виртуальной функции из базового класса, который ее не определяет?
У меня есть следующий класс:
class gkLogicBrick
{
public:
gkLogicBrick(gkGameObject* object, gkLogicLink* link, const gkString& name);
virtual ~gkLogicBrick();
virtual gkLogicBrick* clone(gkLogicLink* link, gkGameObject* dest) = 0;
//unimportant function/variables
};
и это подклассы как:
class gkLogicController : public gkLogicBrick
{
gkLogicController(gkGameObject* object, gkLogicLink* link, const gkString& name);
virtual ~gkLogicController() {}
//unimportant function/variables
};
Метод с именем clone()
не переопределяется, и все же он вызывается из другого класса на gkLogicController
объект. Я думал, что вызывать чисто виртуальные функции не разрешалось? Компиляторы C++ автоматически создают определение по умолчанию для любых унаследованных чисто виртуальных функций?
3 ответа
Можно вызывать чисто виртуальную функцию (через механизм динамической отправки). Это на самом деле цель чисто виртуальных функций, когда вы думаете об этом.
Я предполагаю, что "вызывается из другого класса на gkLogicController
объект "на самом деле означает через указатель или ссылку на gkLogicController
, Это должно затем указать / обратиться к экземпляру класса, производного от gkLogicController
который переопределяет clone
, Невозможно создать экземпляр gkLogicController
сам, как это все еще абстрактно.
Я думаю, вы не скомпилировали свой код. Так как
struct A
{
virtual void test()=0;
};
struct B : A
{
};
int main()
{
B b;
}
увидеть ошибку:
prog.cpp: В функции 'int main()': prog.cpp:13:7: ошибка: невозможно объявить переменную 'b' абстрактного типа 'B' prog.cpp:6:8: note: потому что следующее виртуальные функции являются чистыми внутри 'B': prog.cpp:3:18: note: virtual void A::test()
Если вы не определили функцию SOMEWHERE в реальном классе (например, в производном классе), вы получите ошибку при попытке создать объект (во время компиляции).
Однако хорошо не иметь его в базовом классе, если базовый класс никогда не создается напрямую - фактически, его часто используют таким образом, просто чтобы убедиться, что базовый класс случайно не "используется", когда это не должно быть. Если базовый класс предназначен для использования, вам необходимо реализовать функцию (вы все равно можете сделать это, даже если она говорит = 0
в конце.
И весь смысл виртуальных функций состоит в том, чтобы позволить базовому классу (или некоторому другому компоненту, который знает только о базовом классе) вызывать фактическую функцию в производном классе.