El estándar ISO C ++ especifica que se deben definir todos los métodos virtuales de una clase que no sean puramente virtuales.
En pocas palabras, la regla es:
si su clase derivada anula el método virtual de la clase Base, entonces también debería proporcionar una definición.
Según la regla anterior en su ejemplo de código, virtual void bar();
necesita una definición en la clase Base.
Referencia:
Estándar C ++ 03: 10.3 Funciones virtuales [class.virtual]
Una función virtual declarada en una clase deberá definirse o declararse pura (10.4) en esa clase, o ambas; pero no se requiere diagnóstico (3.2).
Por lo tanto, debe hacer que la función sea puramente virtual o proporcionar una definición para ella.
El faq de gcc también lo documenta:
El estándar ISO C ++ especifica que todos los métodos virtuales de una clase que no son puramente virtuales deben definirse, pero no requiere ningún diagnóstico de violaciones de esta regla [class.virtual]/8
. Con base en esta suposición, GCC solo emitirá los constructores definidos implícitamente, el operador de asignación, el destructor y la tabla virtual de una clase en la unidad de traducción que define su primer método no en línea.
Por lo tanto, si no logra definir este método en particular, el enlazador puede quejarse de la falta de definiciones para símbolos aparentemente no relacionados. Desafortunadamente, para mejorar este mensaje de error, podría ser necesario cambiar el vinculador, y esto no siempre se puede hacer.
La solución es asegurar que todos los métodos virtuales que no sean puros estén definidos. Tenga en cuenta que se debe definir un destructor incluso si se declara virtual puro [class.dtor]/7
.