Może się to wydawać prostym pytaniem, ale nie mogę znaleźć odpowiedzi nigdzie indziej.
Załóżmy, że mam:
class Abstract {
public:
virtual void foo() = 0;
virtual void bar();
}
class Derived : Abstract {
public:
virtual void foo();
}
Czy to w porządku, że klasa Derived nie implementuje funkcji bar ()? A co, jeśli nie WSZYSTKIE moje klasy pochodne wymagają funkcji bar (), ale niektóre tak. Czy wszystkie funkcje wirtualne abstrakcyjnej klasy bazowej muszą być zaimplementowane w klasach pochodnych, czy tylko te, które są czysto wirtualne? Dzięki
źródło
Derived::bar
ma korpus funkcji, czyliAbstract::bar
. Wydaje się więc, że jednostka tłumaczeniowa, w której została zdefiniowana (czy jest w ogóle zdefiniowana?), Nie jest połączona z jednostką tłumaczeniową, w której została wywołana.They only need to implement the pure ones.
To jest mylące. Klasy pochodne nie muszą też koniecznie implementować czystych funkcji wirtualnych.W klasach pochodnych trzeba zaimplementować tylko czyste metody wirtualne, ale nadal potrzebujesz definicji (a nie tylko deklaracji) innych metod wirtualnych. Jeśli go nie podasz, linker może bardzo narzekać.
Zatem samo wstawienie
{}
po opcjonalnej metodzie wirtualnej daje pustą domyślną implementację:class Abstract { public: virtual void foo() = 0; // pure virtual must be overridden virtual void bar() {} // virtual with empty default implementation }; class Derived : Abstract { public: virtual void foo(); };
Bardziej skomplikowana domyślna implementacja została jednak umieszczona w oddzielnym pliku źródłowym.
źródło
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]
Więc albo powinieneś uczynić tę funkcję czystą wirtualną, albo podać jej definicję.
W gcc FAQ doccuments nim również:
źródło
Tak, w porządku ... wystarczy zaimplementować czyste funkcje wirtualne, aby utworzyć instancję klasy pochodzącej z abstrakcyjnej klasy bazowej.
źródło
Tak, to prawda, że klasa pochodna musi nadpisywać funkcję, która jest czystą wirtualną w klasie nadrzędnej. Klasa nadrzędna mająca czystą funkcję wirtualną jest nazywana klasą abstrakcyjną tylko dlatego, że jej klasa potomna musi dawać własne ciało czystej funkcji wirtualnej.
Dla normalnych funkcji wirtualnych: - Nie jest konieczne dalsze nadpisywanie ich, ponieważ niektóre klasy potomne mogą mieć tę funkcję, a inne mogą jej nie mieć.
Głównym celem mechanizmu funkcji wirtualnej jest polimorfizm w czasie wykonywania, niezależnie od tego, czy głównym celem czystej funkcji wirtualnej (klasy abstrakcyjnej) jest uczynienie obowiązkowym posiadanie tej samej nazwy funkcja w treści własnej.
źródło