Virtuelle Destruktoren sind nützlich, wenn Sie möglicherweise eine Instanz einer abgeleiteten Klasse durch einen Zeiger auf die Basisklasse löschen können:
class Base
{
// some virtual methods
};
class Derived : public Base
{
~Derived()
{
// Do some important cleanup
}
};
Hier werden Sie feststellen, dass ich den Destruktor von Base nicht als virtual
. Schauen wir uns nun den folgenden Ausschnitt an:
Base *b = new Derived();
// use b
delete b; // Here's the problem!
Da der Destruktor von Base nicht virtual
y b
ist eine Base*
und zeigt auf eine Derived
Objekt, delete b
hat undefiniertes Verhalten :
[In delete b
], wenn der statische Typ des zu löschenden Objekts von seinem dynamischen Typ abweicht, wird der statische Typ eine Basisklasse des dynamischen Typs des zu löschenden Objekts sein zu löschenden Objekts und der statische Typ muss einen virtuellen Destruktor haben oder das Verhalten ist undefiniert .
In den meisten Implementierungen wird der Aufruf des Destruktors wie jeder nicht-virtuelle Code aufgelöst, was bedeutet, dass der Destruktor der Basisklasse aufgerufen wird, nicht aber der der abgeleiteten Klasse, was zu einem Ressourcenleck führt.
Zusammenfassend lässt sich sagen, dass die Destruktoren der Basisklassen immer virtual
wenn sie für polymorphe Manipulationen gedacht sind.
Wenn Sie das Löschen einer Instanz durch einen Basisklassenzeiger verhindern wollen, können Sie den Destruktor der Basisklasse geschützt und nicht-virtuell machen; dadurch lässt der Compiler den Aufruf von delete
auf einen Zeiger einer Basisklasse.
Mehr über Virtualität und den Destruktor der virtuellen Basisklasse erfahren Sie in dieser Artikel von Herb Sutter .