Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Konstruktor abbrechen
freedy - Mi 30.09.09 14:43
Titel: Konstruktor abbrechen
Hallo Forum,
kennt ihr eine Möglichkeit den Konstruktor zu unterbrechen und eine Instanz nicht anzulegen, wenn beim Anlegen ein Fehler aufgetreten ist?
Ich habe probiert mit Raise eine Exception aufzurufen. Das gibt aber am Programmende nur Probleme mit nicht freigegebenen Speicher.
Ein Beispiel für diesen Bedarf ist z. B. folgendes: der Konstruktor erwartet ein Owner-Objekt. Wenn dieses aber nil ist, soll die Instanz der Klasse nicht angelegt werden. Bisher habe ich mich noch nicht getraut, innerhalb des Konstruktors ein Free aufzurufen, weil ich denke, dass das ein totales Chaos gibt.
Habt ihr einen Rat?
Grüße,
Micha
Tastaro - Mi 30.09.09 14:59
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36:
| type EEinFehler = class(exception) end;
TKlasse = class(tobject) private FIrgendwas: TIrgendwas; public constructor create(EinObjekt: TEinObjekt);
destructor Destroy; override; end;
implementation
constructor TKlasse.create(EinObjekt: TEinObjekt); begin inherited create; FIrgendwas := nil; if not assigned(EinObject) then raise EEinFehler.create('oO') else FIrgendwas := TIrgendwas.create; end;
destructor TKlasse.destroy; begin if assigned(FIrgendwas) then FIrgendwas.free; inherited destroy; end; |
Beste Grüße
Gausi - Mi 30.09.09 15:07
Ich bin mir da nicht ganz sicher, aber das Free im Constructor scheint erlaubt zu sein.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| type TTest = class(TObject) constructor Create(f: Boolean); end;
Constructor tTest.Create(f: Boolean); begin if not f then free; end;
TTest.Create(false); TTest.Create(True); |
Tastaro - Mi 30.09.09 15:23
Wenn man den Konstruktor mit einer Exception abbricht gibt es meines Wissens und meiner Erfahrung nach kein Memoryleak.
Beste Grüße
freedy - Mi 30.09.09 15:37
Tastaro hat folgendes geschrieben : |
Wenn man den Konstruktor mit einer Exception abbricht gibt es meines Wissens und meiner Erfahrung nach kein Memoryleak |
Richtig. Habe ich nochmal mit einer Testklasse probiert. Dann muss mein Fehler irgendwo anders liegen. Jedenfalls bekomme ich bei Abbruch zwei Memoryleaks (1x String, 1x Exception).
Vielen Dank erstmal.
dummzeuch - Mi 30.09.09 21:25
freedy hat folgendes geschrieben : |
kennt ihr eine Möglichkeit den Konstruktor zu unterbrechen und eine Instanz nicht anzulegen, wenn beim Anlegen ein Fehler aufgetreten ist?
Ich habe probiert mit Raise eine Exception aufzurufen. Das gibt aber am Programmende nur Probleme mit nicht freigegebenen Speicher.
|
Wenn man im Konstruktor eine Exception ausloest, so wird automatisch der zugehoerige Destruktor aufgerufen. Dh. der Destruktor muss damit klarkommen, dass evtl. das Objekt nur teilweise erzeugt ist. Das ist in der Regel kein Problem, weil alle Felder mit 0 / NIL / Leerstring initialisiert werden, also folgendes einfach nur funktioniert:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| constructor TMyObject.Create; begin inherited Create; raise Exception.Create('Test'); FMyList := TList.Create; end;
destructor TMyObject.Destroy; begin FMyList.Free; inherited; end; |
Da FMyList mit NIL initialisiert wird, kann man im Destruktor einfach FMyList.Free (oder alternativ FreeAndNil(FMyList)) aufrufen, da die Methode Free ueberprueft, ob SELF <> NIL ist.
Der langen Rede kurzer Sinn: Exceptions sind durchaus dazu geeignet, die Erzeugung eines Objekts im Konstruktor zu verhindern. Bei korrekten Destruktoren sollte es dabei auch keine Speicherlecks geben.
twm
BenBE - Do 01.10.09 09:41
Innerhalb des Konstruktors ist der Aufruf der Funktion Fail erlaubt. Dabei wird eine Exception ausgelöst, die bereits angelegte Instanz wieder freigegeben und die Kontrolle an den nächst-höheren Exception-Handler gegeben.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!