Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Create-Ergebnis verhindern
MitschL - Mo 10.01.05 16:21
Titel: Create-Ergebnis verhindern
Ich grüße mal ganz brav und möchte aufgrund von geringer Sicht wegen Holz vor Augen gleich zum Thema kommen.
Ich möchte beim Instanziieren eines Objektes diese Instanz nicht anlegen, wenn ein Fehler vorliegt.
Ich habe mal - um dem Detail die Ehre zu geben - eine Klasse, die mit einer wichtigen Datei arbeitet, so konstruieren lassen.
Delphi-Quelltext
1: 2: 3: 4: 5:
| type FileClass = class( TObject ) public
constructor Create( path: String ); reintroduce; |
// blablabla
end;
Ich möchte meine Fehlerbehandlung nun nach außen heben, indem ich die Instanz nur anlegen lasse, wenn die Datei existiert.
Damit ich dann sowas machen kann:
Delphi-Quelltext
1: 2: 3:
| myInstance := FileClass.Create( path ); if myInstance = nil then |
Ich kann das Objekt ja eigentlich nicht im Create wieder freigeben, also muß ich das Instanziieren des selben verhindern, oder?
Wenn einer eine Antwort weis, wäre ich geradezu verzückt, so hören zu dürfen
gegrüßt!
MitschL
Moderiert von
Tino: Topic aus Sonstiges verschoben am Do 13.01.2005 um 10:01
Stefan.Buchholtz - Mo 10.01.05 16:58
Das lässt sich einfach erreichen, wenn du den Konstruktor beim Auftreten der Fehlerbedingung einfach eine Exception werfen lässt. Dann wird sofort der Destruktor aufgerufen und das Objekt wieder freigegeben.
Du solltest die Exception natürlich in dem Code, der das Objekt erzeugt, behandeln, wenn du nicht eine häßliche Fehlermeldung haben willst. Ausserdem sollte der Destruktor mit einem unvollständig initialisierten Objekt klarkommen - der Konstruktor wurde ja noch gar nicht komplett ausgeführt.
Stefan
bttb930 - Mo 10.01.05 17:07
oder mach's doch mit einer klassenfunktion die dir eine instanz zurück gibt wenn die datei existiert:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| TTest = class public constructor Create(aPath: string); class function test(aPath: string):TTest; end;
class function TTest.test(aPath: string):TTest; begin if FileExists(aPath) then Result := TTest.Create(aPath) else Result := nil; end;
... Test := TTest.Test('c:\test.txt'); |
MitschL - Mo 10.01.05 17:42
Ich danke euch schonmal,
@ Stefan.Buchholtz: Exception-Handling kam mir auch in den Sinn, ist in meinem Code aber seltener vertreten. Man kann das als ganz persönlichen Splin abtun.
Stefan.Buchholtz hat folgendes geschrieben: |
Ausserdem sollte der Destruktor mit einem unvollständig initialisierten Objekt klarkommen - der Konstruktor wurde ja noch gar nicht komplett ausgeführt. |
Dann muß man doch an genau den Destruktor rankommen können. :twisted:
bttb930 hat folgendes geschrieben: |
oder mach's doch mit einer klassenfunktion die dir eine instanz zurück gibt wenn die datei existiert: |
Dann habe ich eine globale Variable. Hm. Gefällt mir nicht sonderlich. Schade, daß es keine statischen Variablen in Delphi gibt, dann wäre das mit einer Klassenmethode einfacher.
Mich deucht, es wird das Exception-Handling. :?
oder, was mir mehr zusagt. 8)
gegrüßt!
MitschL
Stefan.Buchholtz - Mo 10.01.05 17:57
MitschL hat folgendes geschrieben: |
bttb930 hat folgendes geschrieben: | oder mach's doch mit einer klassenfunktion die dir eine instanz zurück gibt wenn die datei existiert: |
Dann habe ich eine globale Variable. Hm. Gefällt mir nicht sonderlich. Schade, daß es keine statischen Variablen in Delphi gibt, dann wäre das mit einer Klassenmethode einfacher.
Mich deucht, es wird das Exception-Handling. :?
oder, was mir mehr zusagt. 8)
gegrüßt!
MitschL |
Mit der Klassenfunktion brauchst du keine globale Variable - du kannst die aufrufen, wie du den Konstruktor aufrufen würdest.
Ob man diese Lösung oder eine Exception benutzt, ist dann Geschmackssache... :)
Delete - Mo 10.01.05 18:17
Die Delphi Hilfe sagt zu TObject.Create:
Zitat: |
Note: If an exception escapes from a constructor, the object’s destructor is called to clean up the failed instance.
|
Sprich, man brauch selber keine Exception zu werfen, der Destruktor wird automatisch aufgerufen, wenn eine Exception auftritt.
Stefan.Buchholtz - Mo 10.01.05 18:39
Luckie hat folgendes geschrieben: |
Die Delphi Hilfe sagt zu TObject.Create:
Zitat: |
Note: If an exception escapes from a constructor, the object’s destructor is called to clean up the failed instance.
|
Sprich, man brauch selber keine Exception zu werfen, der Destruktor wird automatisch aufgerufen, wenn eine Exception auftritt. |
Genau dieses Verhalten nutzt mein Vorschlag ja aus - die ursprüngliche Frage ging ja darum, wie man die Erzeugung des Objekts verhindern kann, wenn im Konstruktor ein Fehler auftritt.
Stefan
MitschL - Mo 10.01.05 18:59
Ich wieder,
Stefan.Buchholtz hat folgendes geschrieben: |
Mit der Klassenfunktion brauchst du keine globale Variable - du kannst die aufrufen, wie du den Konstruktor aufrufen würdest.
Ob man diese Lösung oder eine Exception benutzt, ist dann Geschmackssache... :) |
Ich hab Bohnen auf die Glühsen. War ja nur der Aufruf unter der Klassendeklaration von bttb930.
Vorsichtshalber sollte ich doch aber den Konstruktor in den private-Bereich verziehen und durch reintroduce, das Vererbende verhindern, oder?
Ich tendiere zu dieser Methode und danke brav.
gegrüßt!
MitschL
Stefan.Buchholtz - Mo 10.01.05 19:04
MitschL hat folgendes geschrieben: |
Ich wieder,
Vorsichtshalber sollte ich doch aber den Konstruktor in den private-Bereich verziehen und durch reintroduce, das Vererbende verhindern, oder?
Ich tendiere zu dieser Methode und danke brav.
gegrüßt!
MitschL |
Der Konstruktor kann dann private sein - du würdest die Klasse dann ja nur über die Klassenfunktion erzeugen.
Stefan
Delete - Mo 10.01.05 19:24
Stefan.Buchholtz hat folgendes geschrieben: |
Genau dieses Verhalten nutzt mein Vorschlag ja aus - die ursprüngliche Frage ging ja darum, wie man die Erzeugung des Objekts verhindern kann, wenn im Konstruktor ein Fehler auftritt.
|
Brauchst du ja gar nicht verhindern, da das Objekt ja automatisch wieder zerstört wird, wenn eine Exception im Konstruktor auftriit.
Stefan.Buchholtz - Mo 10.01.05 19:36
Luckie hat folgendes geschrieben: |
Brauchst du ja gar nicht verhindern, da das Objekt ja automatisch wieder zerstört wird, wenn eine Exception im Konstruktor auftriit. |
Das ist klar. Es ging eben darum, die Exception selbst zu werfen, wenn der Konstruktor selbst ein Problem feststellt, also z.B. sowas:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| constructor TTest.Create(fileName: string); begin if not FileExists(fileName) then begin raise ETestException.CreateFmt('Datei %s nicht gefunden!', [fileName]); end; ... end; |
Stefan
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!