Machen Sie alle Destruktoren virtuell, es sei denn, Sie haben gute Gründe, dies nicht zu tun.
Sonst passiert so etwas Böses:
Angenommen, Sie haben ein Array von Fruit-Zeigern mit den beiden Objekten Apple und Orange.
Wenn Sie aus der Sammlung von Fruit-Objekten löschen, ~Apple() und ~Orange() werden nicht aufgerufen, es sei denn, ~Fruit() ist virtuell.
Richtig gemachtes Beispiel:
#include <iostream>
using namespace std;
struct Fruit { // good
virtual ~Fruit() { cout << "peel or core should have been tossed" << endl; }
};
struct Apple: Fruit { virtual ~Apple() {cout << "toss core" << endl; } };
struct Orange: Fruit { virtual ~Orange() {cout << "toss peel" << endl; } };
int main() {
Fruit *basket[]={ new Apple(), new Orange() };
for (auto fruit: basket) delete fruit;
};
gute Leistung
toss core
peel or core should have been tossed
toss peel
peel or core should have been tossed
Beispiel falsch gemacht:
#include <iostream>
using namespace std;
struct Fruit { // bad
~Fruit() { cout << "peel or core should have been tossed" << endl; }
};
struct Apple: Fruit { virtual ~Apple() {cout << "toss core" << endl; } };
struct Orange: Fruit { virtual ~Orange() {cout << "toss peel" << endl; } };
int main() {
Fruit *basket[]={ new Apple(), new Orange() };
for (auto fruit: basket) delete fruit;
};
schlechte Leistung
peel or core should have been tossed
peel or core should have been tossed
(Hinweis: Wo ich der Einfachheit halber struct verwendet habe, verwende ich normalerweise class und gebe public an)