![]() |
Objekterstellung im Konstruktor abbrechen
Hallo zusammen,
ich hoffe, dass diese Frage ausnahmsweise mal keine so harte Nuss ist wie meine anderen... :mrgreen: Also zum Thema: Ich habe ein Formular mit überschriebenem Create()-Konstruktor, welches dynamisch erstellt wird. Falls eine bestimmte Funktion, die in diesem Konstruktor aufgerufen wird, fehlschlägt (keine Exception, sondern Rückgabewert False), soll die Erstellung des Formulars abgebrochen und es wieder freigegeben werden. Ein Referenz-Parameter im Konstruktor gibt Aufschluss darüber, ob diese bestimmte Funktion fehl schlug oder nicht.
Delphi-Quellcode:
Klar, ich könnte statt Free (was einen bösen Fehler verursacht) eine Exception auslösen und diese beim Create-Aufruf abfangen. Aber ich möchte es einfach eleganter (-> ASuccess)... :???:
constructor TMyForm.Create(AOwner: TComponent; AMyP: Integer; var ASuccess: Boolean);
begin [...] if not MyFunc(AMyP) then begin Free(); // Oje, das endet böse... Exit; end; [...] end; Gibt es da einen anderen Lösungsweg? Ich bin dankbar für jeden Lösungsvorschlag! :-D Grüße, Marco P.S.: Damit keiner meckert: :warn: Dieser Beitrag hätte zwar auch ins Forum "VCL / WinForms / Controls" gepasst, da die Frage sich aber eher allgemein auf Objekte als speziell auf "das Formular" bezieht, habe ich sie hier reingestellt. |
Re: Objekterstellung im Konstruktor abbrechen
Wieso sind Exceptions nicht elegant?
Delphi-Quellcode:
Try
anObject := TMyObject.Create; anOnject.DoSomeThing; anObject.AProperty := FooBar Except Showmessage('Das Objekt konnte nicht erzeugt werden') End; |
Re: Objekterstellung im Konstruktor abbrechen
Überschreib TObject.ClassInstance. In der Code-Lib gibt's ein Beispiel (
![]() @alzaimar: Wenn das Haptprogramm diese Exception dann nicht abfängt... |
Re: Objekterstellung im Konstruktor abbrechen
Zitat:
Die Frage die ich mir stelle: Ist es sinnvoll das mit der Variable zu machen? Immerhin ist es ja fast normal das man mit Try-Except arbeitet. Oder noch besser gefragt: Was ist der Grund das ich ein Objekt nicht erzeugen kann? Dies sollte ja ein böser Fehler sein und dann finde ich es besser dies mit den Standardmöglichkeiten zu machen. |
Re: Objekterstellung im Konstruktor abbrechen
oder du machst eine
Class Function CheckAndCreate; Die dir die Instanz zurückliefert oder auch NIL falls deine Prüfung entsprechendes sagt.
Delphi-Quellcode:
mfg
Class Function TMyObj.CheckAndCreate : TMyObj;
begin result = TMyObj.Create; if not result.Check then begin freeandnil (result); end; end; Der Dan |
Re: Objekterstellung im Konstruktor abbrechen
Hi PHistev,
Dein Einwand ist sinnlos. Wer die Exception nicht abfängt wird auch den Flag 'Success' nicht abfragen. Aber wenn die Exception nicht abgefangen wird, passiert zumindest eins nicht: "Nil Pointer exception" Deine Variante:
Delphi-Quellcode:
Meine Variante:
...
MyObject := TMyObject.Create (Success); MyObject.DoSomething; // <-- Phatoomp, wenn Success = False, ...
Delphi-Quellcode:
Frage: Was ist besser? Was ist sicherer? Was führt vielleicht mal zu unangenehmen Effekten?
...
MyObject := TMyObject.Create; MyObject.DoSomething; // <-- Wird erst gar nicht ausgeführt, und der Anwender sieht, wie gut der Entwickler ist! ... @DerDan: Noch eine Möglichkeit. Viele Wege führen nach Rom. Aber Dein Weg ist wenigstens gepflastert :zwinker: Hat aber einen Nachteil: Es wird ein illegales Objekt erzeugt. Es kann ja sein, das das Objekt einfach nicht erzeugt werden _kann_ (oder nur mit Schwierigkeiten). Ich bleib dabei: Mit Exception ist's am einfachsten. Vielleicht sogar mit der ClassFunction von DerDan. |
Re: Objekterstellung im Konstruktor abbrechen
Zitat:
Das kann man ja in die Function Check reinlegen. Von da her seh ich keine Situation bei der man nicht mal erst ein Object anlegen können sollte. Wird übrigens bei allen anderen Varianten hier in den obigen beispielen auch gemacht |
Re: Objekterstellung im Konstruktor abbrechen
Hallo zusammen,
danke erstmal für die zahlreichen Antworten... :-D Nun, zum besseren Verständnis der Situation: Ich will direkt im Create-Konstruktor des Formulars Daten in selbiges laden. Da dies aber scheitern kann, soll bei einem Fehler die Erstellung der Form abgebrochen werden. Die Funktion zum Laden der Daten verursacht bei Fehlern (normalerweise) keine Exception, sondern gibt den Erfolg über Result zurück. Die beste Lösung meines Problems ist wohl die Kombination von "Exception" und ASuccess.
Delphi-Quellcode:
Tjaja, diese Abort-Prozedur hat mir gefehlt... :stupid:
constructor TMyForm.Create(AOwner: TComponent; AMyP: Integer; var ASuccess: Boolean);
begin ASuccess := False; [...] if not MyFunc(AMyP) then Abort(); // Aha... [...] ASuccess := True; end; [...] try TMyForm.Create(Self, 123, Success); except if not ASuccess then // Funktion gescheitert end; [...] Richtig Sinn macht ASuccess zugegebenermaßen eigentlich erst, wenn es über eine Enumeration Aufschluss über den Erfolg bzw. Nichterfolg der Formularerstellung gibt, was sich aber problemlos erweitern lässt. Viele Grüße, Marco |
Re: Objekterstellung im Konstruktor abbrechen
Ich würde mich mal näher mit Exceptions, bzw. der Programmflusskontrolle beschäftigen. Dann kannst Du ziemlich elegant deine 'Enumeration' vergessen und den Grund des Scheiterns komplett über Exceptions abbilden. Du definierst Dir einfach verschiedene Exceptionklassen, die Du individuell abfangen kannst (steht alles in der OH)
Delphi-Quellcode:
So hast Du eine strikte Trennung im Programm. Der normale Programmfluss ist klar sichtbar und die Fehlerbehandlung ist abgegrenzt.
Type
EWrongParameter = Class (Exception); EInvalidUsage = Class (Exception); ... Constructor TMyObject.Create (aParameter : TSomeType); Begin Inherited; If UsageInvalid Then Raise EInvalidUsage.Create ('Some Text'); If Not CheckParameter (aParameter) Then Raise EWrongParameter.CreateFmt('Wrong parameter type %s',[aParameter]); ... End; ... Begin Try oMyObject := TMyObject.Create; oMyObject.CanCallMethods; Except On E:EInvalidUsage Do HandleError; On E:EWrongParameter Do HandleAnotherError; // Alle anderen Fehler (Speicher etc.) werden nicht abgefangen und werden weitergeleitet! End; ... End; |
Re: Objekterstellung im Konstruktor abbrechen
Hallo Alzaimar,
Zitat:
Gruß, Marco |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:24 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz