Destruktoraufruf
-
Hallo,
ich habe eine Klasse von der ich ableite. Den Super-Konstruktor rufe ich bereits auf.
Nun würde ich gerne im Destruktor auch noch den Super-Destruktor aufrufen. Geht das?
Wenn ja, wie?Vielen dank
class SuperClass() { SuperClass(int a) { ... } ~SuperClass(void) { ... } } class SubClass() : public SuperClass { SubClass(int a) : SuperClass(a) { ... } ~SubClass(void) { ?????? ->Destruktoraufruf von SuperClass } }
-
Der Destruktor wird automatisch aufgerufen, nachdem dein Destruktor fertig ist. Das kannst du auch nicht verhindern.
Der Defaultkonstruktor wird übrigens auch automatisch aufgerufen (vor deinem Konstruktor). Wenn es keinen Default-Konstruktor gibt und du nicht manuell einen anderen Konstruktor aufrufst, gibt es einen Fehler.
-
Danke für die schnelle Antwort.
Ist es ratsam den Destruktor virtuell zu machen oder bleibt sich das gleich?
-
Bei Klassen die als Basis / Interface dienen:
Destruktor entweder public virtual ODER protected non-virtual.
-
Ist es nicht immer so, dass der Destruktor der abgeleitetn Klasse zuerst aufgerufen wird und dann immer automatish, ob man es will oder nicht, der Destruktor der Mutterklasse aufgerufen wird.
So ähnlich läuft es doch mit den Konstruktoren. Erst wird der Konstruktor der Mutterklasse, dann der der abgeleiteten Klasse aufgerufen.
lg, freakC++
-
freakC++ schrieb:
Ist es nicht immer so, dass der Destruktor der abgeleitetn Klasse zuerst aufgerufen wird und dann immer automatish, ob man es will oder nicht, der Destruktor der Mutterklasse aufgerufen wird.
So ähnlich läuft es doch mit den Konstruktoren. Erst wird der Konstruktor der Mutterklasse, dann der der abgeleiteten Klasse aufgerufen.
lg, freakC++Ja, richtig.
SubKlasse* sub=new SubKlasse; delete sub;//ruft ~SubKlasse auf und der ruft am Ende automatisch ~Superklasse auf.Aber
SubKlasse* sub=new SubKlasse; SuperKlasse* super=sub;//darf ja, weil vererbt delete super;//Fall A: ~SuperKlasse ist nicht virtuell: Bumm, ~SubKlasse wird nicht aufgerufen. En eventueller string SubKlasse::str wird nicht destruiert. //Fall B: ~SuperKlasse ist virtuell. Zur Laufzeit wird der richtige Destruktoreinsprung gefunden, also ~SubKlasse (und der ruft bekanntlich am Ende automatisch ~Superklasse auf).Und man kann davon ausgehen, daß der Benutzer irgendwann mal den Zeigertrick macht. Daher die Empfehlung, Basisklassendestruktoren generell virtuell zu machen.
-
volkard schrieb:
SubKlasse* sub=new SubKlasse; SuperKlasse* super=sub;//darf ja, weil vererbt delete super;//Fall A: ~SuperKlasse ist nicht virtuell: Bumm, ~SubKlasse wird nicht aufgerufen. En eventueller string SubKlasse::str wird nicht destruiert.Korrigiere: Fall A: ~SuperKlasse ist nicht virtuell. Bumm, undefiniertes Verhalten. Jetzt kann alles passieren, aber ziemlich sicher nicht was man möchte/erwartet.
Und man kann davon ausgehen, daß der Benutzer irgendwann mal den Zeigertrick macht. Daher die Empfehlung, Basisklassendestruktoren generell virtuell zu machen.
Alternativ protected und nicht virtuell, wie schon erwähnt. Verhindert Fall A und B, erlaubt nur das erste Beispiel.