Standard ISO C ++ określa, że należy zdefiniować wszystkie metody wirtualne klasy, które nie są czysto wirtualne.
Mówiąc najprościej, zasada jest taka:
Jeśli Twoja klasa pochodna zastępuje metodę wirtualną klasy bazowej, powinna również zawierać definicję. Jeśli nie, to klasa podstawowa powinna zawierać definicję tej metody.
Zgodnie z powyższą regułą w przykładowym kodzie virtual void bar();
wymaga definicji w klasie bazowej.
Odniesienie:
C ++ 03 Standard: 10.3 Funkcje wirtualne [class.virtual]
Funkcja wirtualna zadeklarowana w klasie powinna zostać zdefiniowana lub zadeklarowana jako czysta (10.4) w tej klasie lub obie; ale nie jest wymagana żadna diagnostyka (3.2).
Więc albo powinieneś uczynić tę funkcję czystą wirtualną, albo podać jej definicję.
W gcc FAQ doccuments nim również:
Standard ISO C ++ określa, że wszystkie metody wirtualne klasy, które nie są czysto wirtualne, muszą być zdefiniowane, ale nie wymagają żadnej diagnostyki w przypadku naruszenia tej reguły [class.virtual]/8
. Opierając się na tym założeniu, GCC będzie emitować tylko niejawnie zdefiniowane konstruktory, operator przypisania, destruktor i wirtualną tabelę klasy w jednostce translacji, która definiuje swoją pierwszą taką metodę nieliniową.
Dlatego jeśli nie zdefiniujesz tej konkretnej metody, linker może narzekać na brak definicji dla pozornie niepowiązanych symboli. Niestety, aby poprawić ten komunikat o błędzie, może być konieczna zmiana konsolidatora, a nie zawsze można to zrobić.
Rozwiązaniem jest zapewnienie, że wszystkie metody wirtualne, które nie są czyste, są zdefiniowane. Należy zauważyć, że destruktor musi być zdefiniowany, nawet jeśli jest zadeklarowany jako czysto wirtualny [class.dtor]/7
.