Lo standard ISO C ++ specifica che tutti i metodi virtuali di una classe che non sono puramente virtuali devono essere definiti.
In poche parole, la regola è:
se la tua classe derivata sovrasta il metodo virtuale della classe Base, dovrebbe fornire anche una definizione, in caso contrario la classe Base dovrebbe fornire la definizione di quel metodo.
Come per la regola precedente nel tuo esempio di codice, virtual void bar();necessita di una definizione nella classe Base.
Riferimento:
Standard C ++ 03: 10.3 Funzioni virtuali [class.virtual]
Una funzione virtuale dichiarata in una classe deve essere definita, o dichiarata pura (10.4) in quella classe, o entrambe; ma non è richiesta alcuna diagnostica (3.2).
Quindi o dovresti rendere la funzione puro virtuale o fornirne una definizione.
Anche le faq di gcc lo documentano:
Lo standard ISO C ++ specifica che tutti i metodi virtuali di una classe che non sono puramente virtuali devono essere definiti, ma non richiede alcuna diagnostica per le violazioni di questa regola [class.virtual]/8. Sulla base di questo presupposto, GCC emetterà solo i costruttori definiti implicitamente, l'operatore di assegnazione, il distruttore e la tabella virtuale di una classe nell'unità di traduzione che definisce il suo primo metodo non in linea.
Pertanto, se non si riesce a definire questo particolare metodo, il linker potrebbe lamentarsi della mancanza di definizioni per simboli apparentemente non correlati. Sfortunatamente, per migliorare questo messaggio di errore, potrebbe essere necessario modificare il linker e non è sempre possibile farlo.
La soluzione è garantire che tutti i metodi virtuali non puri siano definiti. Si noti che un distruttore deve essere definito anche se dichiarato puro virtuale [class.dtor]/7.