Wozu virtual Destruktor
-
Hallo,
Mir ist aufgefallen, dass Tools wie VC beim erstellen eines Projektes den Destruktor immemr als virtual definieren.
class Ce8Modell { public: Ce8Modell(); virtual ~Ce8Modell(); ...
Wozu soll das gut sein?
Ich habe von dieser Klasse andere abgeleitet sogar mehrfach. Dann habe ich das virtual mal weggenommen, es passiert rein gar nichts. Das Programm läuft wie vorher, genauso wie es soll.
Ich lese immer wieder, der Destruktor muss in der Basisklasse virtual sein, wenn man davon Unterklassen ableitet, aber eine rationale Begründung finde ich nicht. Es ist ja fast logisch, dass man den nicht überschreiben kann da er genauso wie der Konstruktor einen individuellen Namen hat (Klassenname).Es ist sicher keine Weltbewegende und wichtige Frage die ich hier stelle, aber hier bei uns weiss es sogut wie keiner.... Man arbeitet einfach damit und nimmt es so wie es ist.
Aber ich finde es interessant und hoffe dass mir hier im Forum jemand helfen kann.
-
Ich glaube, das kommt dann zum Einsatz, wenn man Objekte dynamisch erzeugt.
Beispiel:BasisKlasse* basispointer; basispointer = new AbgeleiteteKlasse(Konstruktoraufruf); delete basispointer;
Weil der Compiler beim deleten ohne virtuellen Destruktor denkt, er müsse den BasisKlassen-Destruktor verwenden, tut er das und es kann sein, dass dieser Destruktor etwas falsches tut oder etwas nicht macht (Stichwort dynamische Elemente)
geloescht
-
Mach mal ein kleines Beispielprogamm.
Eine Klassenhierachie. In die Destruktoren nd Konstruktoren eine cout Ausgabe einfügen. Dann testen, mit virtual und dann ohne.
Selbst ist der mann.
-
Gut
class A{ // public: virtual void f(); virtual ~A(); }; class B : public A{ // public: //f() und ~B() definieren };
Dann:
int main(){ A* a = new B(); a->f();//da f() eine virtuele Funktion ist, wird B::f() aufgerufen. delete a; // ruft B::~B() auf nur wenn der Destruktor von Klasse A virtuel ist, //sonst wird A::~A() aufgerufen und das kann falsch sein }
-
Eine Klasse, die als Basisikalsse für andere Klassen dient, sollte stets einen virtuellen Destruktor besitzen.
Auch wenn die Basisklasse keinen eigenen Desturktor benötigt, sollte zumindest eine Dummy-Destruktor, d.h. ein Destruktor mit leerem Funktionsrumpf, definiert werden.
-
Geht doch.
-
Ich lese immer wieder, der Destruktor muss in der Basisklasse virtual sein, wenn man davon Unterklassen ableitet, aber eine rationale Begründung finde ich nicht
Eigentlich sollte man in diesem Forum eine rationale Begründung finden, da ich (und andere) eine solche bereits ca. 1,9 Millonen Mal gegeben habe.
Zur Wiederholung:
Der Aufruf von delete auf einem Basisklassenzeiger, der auf ein dynamisch allokiertes Objekt einer abgeleiteten Klasse zeigt, führt zu undefiniertem Verhalten, falls die Basisklasse keinen virtuellen Destruktor besitzt. Fertig.Wie sich undefiniertes Verhalten auswirkt, ist, wie der Name bereits vermuten lässt, undefiniert. Da ist alles möglich: vom formatieren der Festplatte bis zu einer automatisch generierten Mail an deinen Chef.
Das klassische Verhalten in diesem Fall ist aber, dass der Destruktor des dynamischen Typs (und aller Typen die zwischen diesem und dem statischen Typ liegen) nicht aufgerufen wird. Falls die abgeleitete Klasse irgendwelche Ressourcen belegt, die im Destruktor freigegeben werden, so werden diese *nicht* freigegeben und es entstehen Ressourcenlöcher.
Sprich: was du in diesem Fall verlierst ist die wunderschöne Symmetrie zwischen Konstruktor-Aufrufen und Destruktor-Aufrufen.