O padrão ISO C ++ especifica que todos os métodos virtuais de uma classe que não sejam virtuais puros devem ser definidos.
A regra é simplesmente:
se sua classe derivada substituir o método virtual da classe Base, ela também deverá fornecer uma definição. Caso contrário, a classe Base deverá fornecer a definição desse método.
Conforme a regra acima em seu exemplo de código, virtual void bar();
precisa de uma definição na classe Base.
Referência:
Padrão C ++ 03: 10.3 Funções virtuais [class.virtual]
Uma função virtual declarada em uma classe deve ser definida, ou declarada pura (10.4) naquela classe, ou ambos; mas nenhum diagnóstico é necessário (3.2).
Portanto, você deve tornar a função puramente virtual ou fornecer uma definição para ela.
O gcc faq também documenta:
O padrão ISO C ++ especifica que todos os métodos virtuais de uma classe que não sejam virtuais puros devem ser definidos, mas não requer nenhum diagnóstico para violações desta regra [class.virtual]/8
. Com base nessa suposição, o GCC emitirá apenas os construtores definidos implicitamente, o operador de atribuição, o destruidor e a mesa virtual de uma classe na unidade de tradução que define seu primeiro método não embutido.
Portanto, se você não conseguir definir esse método específico, o vinculador pode reclamar da falta de definições para símbolos aparentemente não relacionados. Infelizmente, para melhorar essa mensagem de erro, pode ser necessário alterar o vinculador e isso nem sempre pode ser feito.
A solução é garantir que todos os métodos virtuais que não são puros sejam definidos. Observe que um destruidor deve ser definido mesmo se for declarado virtual puro [class.dtor]/7
.