Стандарт ISO C ++ определяет, что все виртуальные методы класса, которые не являются чисто виртуальными, должны быть определены.
Проще говоря, правило:
Если ваш производный класс переопределяет виртуальный метод Базового класса, то он также должен предоставить определение. Если нет, то Базовый класс должен предоставить определение этого метода.
Согласно приведенному выше правилу в вашем примере кода, virtual void bar();
необходимо определение в базовом классе.
Ссылка:
C ++ 03 Standard:10.3 Виртуальные функции [class.virtual]
Виртуальная функция, объявленная в классе, должна быть определена или объявлена как чистая (10.4) в этом классе, или в обоих;но никакой диагностики не требуется (3.2).
Так что либо вы должны сделать функцию чисто виртуальной, либо предоставить ее определение.
gcc faq также документирует его:
Стандарт ISO C ++ указывает, что все виртуальные методы класса, которые не являютсяДолжен быть определен чисто виртуальный, но не требуется никакой диагностики нарушений этого правила [class.virtual]/8
.Исходя из этого предположения, GCC будет генерировать только неявно определенные конструкторы, оператор присваивания, деструктор и виртуальную таблицу класса в модуле перевода, который определяет его первый такой не встроенный метод.
Поэтому, еслиЕсли вы не можете определить этот конкретный метод, компоновщик может жаловаться на отсутствие определений для явно не связанных символов.К сожалению, чтобы улучшить это сообщение об ошибке, может потребоваться изменить компоновщик, и это не всегда может быть сделано.
Решение состоит в том, чтобы обеспечить определение всех не чистых виртуальных методов.Обратите внимание, что деструктор должен быть определен, даже если он объявлен чисто виртуальным [class.dtor]/7
.