W kodzie poprawionym destruktor klasy baza2 jest wirtualny. Wykonanie fragmentu „Po” spowoduje wywołanie destruktorów obu klas, zarówno klasy Pochodna2, jak i klasy baza2.
Moglibyśmy się kłócić, że podany fragment kodu jest przekombinowany. Naprawdę tak nie jest. Często funkcje pobierają wskaźniki do klas podstawowych i wykonują odpowiednie operacje za pomocą funkcji wirtualnych. Rozwiązanie to pozwala utworzyć ogólne funkcje obsługujące wiele różnych klas pochodnych. Funkcje takie mogą wywoływać instrukcję delete, a w takim wypadku zauważymy opisany przed chwilą problem. Rozważmy następujący kod:
Pochodna2 *pd2;
baza2 *pdb;
pd2 = new Pochodna2;
Przetwarzaj (pd2);
void Przetwarzaj (baza2 *pbaza2)
//wykonać tutaj jakieś operacje delete pbaza2;
Pokazany kod wydaje się zupełnie niewinny. Oglądając go, mogliśmy nawet nie zauważyć rzutowania zmiennej i kryjącego się w nim niebezpieczeństwa.
Podsumowując, jeśli destruktor nie jest wirtualny, to zostanie wywołany destruktor klasy podstawowej, ale nie destruktor klasy pochodnej. A wtedy może stać się coś niedobrego.
Przykład: TestVirtualDTor() w pliku inherit.cpp
unikanie nieoczekiwanych wyników
Przed
class Pochodnal : public bazal
public:
Pochodnal (Pochodnal &pochodna1)
cout « "konstruktor kopiowania Pochodnal \n";