[gelöst] Qt Destruktoren

Alles rund um die Programmierung mit Qt
Antworten
QNoob
Beiträge: 10
Registriert: 13. September 2007 00:35

[gelöst] Qt Destruktoren

Beitrag von QNoob »

Moin,

Sorry schon mal, falls die Frage zu dumm ist, aber ich konnte dazu nichts sinnvolles finden und bin noch ziemlich unerfahren, was C++ angeht.

Ich habe gelesen, dass children Objekte automatisch vom parent gelöscht werden, wenn dieser aufhört zu existieren. Wenn man jetzt den Destruktor einer Qt-Klasse überlädt, geht dann die Funktionalität verloren, dass die children automatisch gelöscht werden? :?
Zuletzt geändert von QNoob am 13. September 2007 12:27, insgesamt 1-mal geändert.
macman
Beiträge: 1738
Registriert: 15. Juni 2005 13:33
Wohnort: Gütersloh
Kontaktdaten:

Beitrag von macman »

Wenn Du eine Funktion erweiterst, dann muss die Funktion der Basisklasse mit aufgerufen werden. Wenn Du sie ersetzt, dann lässt man das eben.
Die deutsche Schriftsprache ist case-sensitive. Außerdem gibt es eine Interpunktionsnorm. Wenn manch einer seine Programme genauso schlampig schreibt, wie sein Posting hier, dann sollte er es lieber bleiben lassen.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

@macman: Es überschreibt nicht eine Funktion sondern einen dtor/ctor!

Es werden immer aller ctors der Reihe nach aufgerufen (von oben nach unten) und am Ende auch alle dtors (auch von oben nach unten). Also nichts mit überschreiben.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
macman
Beiträge: 1738
Registriert: 15. Juni 2005 13:33
Wohnort: Gütersloh
Kontaktdaten:

Beitrag von macman »

Stimmt, nicht bedacht. Der Konstruktor der Basisklasse wird ja auch aufgerufen, ohne das man das explizit machen muss. Warum sollte das dann beim Destruktor nicht auch der Fall sein.
Die deutsche Schriftsprache ist case-sensitive. Außerdem gibt es eine Interpunktionsnorm. Wenn manch einer seine Programme genauso schlampig schreibt, wie sein Posting hier, dann sollte er es lieber bleiben lassen.
Deever
Beiträge: 90
Registriert: 9. Mai 2007 18:20

Beitrag von Deever »

macman hat geschrieben:Der Konstruktor der Basisklasse wird ja auch aufgerufen, ohne das man das explizit machen muss.
Falsch. Oder zumindest misverständlich.

Gruß,
/dev
Volker
Beiträge: 343
Registriert: 30. Juni 2005 05:27

Beitrag von Volker »

Also meiner Meinung nach muss man den Konstruktor der Basisklasse explizit aufrufen, den Destructor jedoch nicht. Allerdings sollte man den Destructor in der Oberklasse deshalb immer virtual machen, da wenn das Objekt auf Basis einer Variablen vom Typ der Oberklasse gelöscht wird, der Unterklassendestruktor nicht aufgerufen wird.
Und demnach wird soweit ich weiß auch der Destruktor von unten nach oben und nicht von oben nach unten aufgerufen.
Bitte seid so nett und ändert den Titel von Beiträgen die gelöst wurden, auf [gelöst] Beitragstitel
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Oj man - so viel Unkenntnis in einem Programmiererforum :(
Also meiner Meinung nach muss man den Konstruktor der Basisklasse explizit aufrufen
Falsch - der Compiler ruft den default ctor auf wenn man nichts angibt.
Und demnach wird soweit ich weiß auch der Destruktor von unten nach oben und nicht von oben nach unten aufgerufen.
Na dann viel Spass... überleg dir mal wie das gehen soll.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
Volker
Beiträge: 343
Registriert: 30. Juni 2005 05:27

Beitrag von Volker »

Also a) ja der Oberklassen Konstruktor wird standardmäßig aufgerufen, war mir neu, aber gut zu wissen. Das gilt allerdings auch nur dann, wenn ein Default Konstruktor ohne Parameter vorhanden ist.

aber b) in folgendem Beispiel wird erst der Unterklassen Destruktor aufgerufen und dann der Oberklassen Destruktor!

Code: Alles auswählen

#ifndef UNTERKLASSE_H_
#define UNTERKLASSE_H_

#include "Oberklasse.h"


class Unterklasse : public Oberklasse
{
public:
	Unterklasse() {std::cout << "Unterklassen Constructor" << std::endl;}
	~Unterklasse() {std::cout << "Unterklassen Destructor" << std::endl;}

};

#endif

Code: Alles auswählen

#ifndef OBERKLASSE_H_
#define OBERKLASSE_H_

#include <iostream>

class Oberklasse
{
public:
	Oberklasse() { std::cout << "Oberklassen Constructor" << std::endl; }
	virtual ~Oberklasse() { std::cout << "Oberklassen Destructor " << std::endl; }


};
#endif

Code: Alles auswählen

#include "Oberklasse.h"
#include "Unterklasse.h"

int main(int argc, char** argv)
{
	Unterklasse* klasse = new Unterklasse();
	delete klasse;
}
Und wie ich bereits geschreiben habe, wenn man die Variable klasse vom Typ Oberklasse macht und den Destructor von Oberklasse nicht virtual, dann wird der Destructor der Unterklasse nicht aufgerufen
Und demnach wird soweit ich weiß auch der Destruktor von unten nach oben und nicht von oben nach unten aufgerufen.
Na dann viel Spass... überleg dir mal wie das gehen soll.
Hab ich mir überlegt! Und bin dabei zu folgendem Schluss gekommen: Angenommen im Oberklassen Destruktor wird etwas gelöscht, auf das der Unterklassen Destruktor noch zugreift, dann würde das in deiner Variante zu einem Crash führen... wäre also nicht sinnvoll oder?
Bitte seid so nett und ändert den Titel von Beiträgen die gelöst wurden, auf [gelöst] Beitragstitel
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Ich glaube mein oben ist dein unten :-D

Ich sehe es als Stack:

class a : public b

a -> oben
b -> unten

das mit dem virtual ist so korrekt. Es wird dann erst in der vtable geschaut und mit dem obersten (nach meiner Leseart) dtor angefangen
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
QNoob
Beiträge: 10
Registriert: 13. September 2007 00:35

Beitrag von QNoob »

Ok, danke für die Antworten. :)

Es ist also so, dass dtors nie "überschrieben" werden, sondern jeder dtor ruft auch automatisch den dtor der Basisklasse auf. Deshalb gibt es dann auch keine Probleme und sobald man virtuelle Funktionen in seiner Klasse hat, muss auch der dtor virtuell sein.

Habe ich das so richtig verstanden?
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Ja.
Ich würde allerdings den dtor immer virtual machen.

Code: Alles auswählen

class a
{
public:
 ~a();
}

class b : publicc a
{
public:
 ~b();
}


a *ptrA= new b();
delete ptrA;
Da sonst im obigen Beispiel ~b nicht aufgerufen wird.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
Volker
Beiträge: 343
Registriert: 30. Juni 2005 05:27

Beitrag von Volker »

Christian81 hat geschrieben:Ich glaube mein oben ist dein unten :-D
Dann ist aber dein vorheriger Kommentar widersprüchlich:
Es werden immer aller ctors der Reihe nach aufgerufen (von oben nach unten) und am Ende auch alle dtors (auch von oben nach unten).
Da ich das so verstehe, dass die Reihenfolge bei beiden gleich wäre. Ist sie aber gerade nicht!
Bitte seid so nett und ändert den Titel von Beiträgen die gelöst wurden, auf [gelöst] Beitragstitel
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Ok, Du hast recht - es ist falsch ausgedrückt. Der 'Body' des ctors wird natürlich erst ausgeführt wenn der ctor der Basisklasse ausgeführt wurde. D.h. er geht erst nach unten und dann wieder nach oben.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Beitrag von RHBaum »

Ich würde allerdings den dtor immer virtual machen.
Was einem wenn man ableitet eigentlich gar nix hilft :-)

Leitest du von ner klasse ab, die nen virtuellen Dtor hat, wird dein Dtor automatisch auch virtuell.
Ich geb Dir aber recht, man sollte das virtual in dem Falle auch dazuschreiben, auch wenns nix mehr bewirkt.

Leitest du von einer klasse ab, die keinen virtuellen Dtor hat, kannst du deinen DTor virtuell machen, die vtable wird dann an deiner klasse angelegt. deleted aber jemand ueber den basiszeiger -> dein Dtor wird nicht aufgerufen -> naja, memleaks und so zeugs.

Wenn du ableitest wird also dein dtor immer virtual sein, oder du leitest von ner klasse ab, die nicht fuers ableiten "gedacht" ist.

Ciao ...
Antworten