Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Exception in Create-Prozedur ohne anschließendes Destroy? (https://www.delphipraxis.net/85885-exception-create-prozedur-ohne-anschliessendes-destroy.html)

robvs 6. Feb 2007 13:25


Exception in Create-Prozedur ohne anschließendes Destroy?
 
Hallo,

ich habe eine Klasse, die bereits im Constructor diverse Zustände abprüft und ggf ein Exception wirft, um eine Behandlung ungewollter Zustände zu ermöglichen. Mein Problem dabei ist, dass leider nach dem Erzeugen der Exception innerhalb des Constructors die Objektinstanz vollautomatisch freigegeben wird, es wird also unmittelbar der Destructor aufgerufen.

Kann man das irgendwie verhindern??

VG

Rob

PS: Ich nutze das BDS2006

dataspider 6. Feb 2007 13:36

Re: Exception in Create-Prozedur ohne anschließendes Destroy
 
Das ist IMHO nicht möglich.
Aber man kann die Routinen evtll. in die Methode AfterConstruction verlagern.
Diese Methode sollte in allen Klassen vorhandensein und kann überschrieben werden.

Cu, Frank

robvs 6. Feb 2007 13:48

Re: Exception in Create-Prozedur ohne anschließendes Destroy
 
Hey Frank und alle anderen,

das habe ich ebenfalls probiert - leider führt auch eine dort ausgelöste Exception zum Aufruf des Destructors.
Kann es sein, dass das mal eine ganz empfindliche Schwachstelle im exception handling von Delphi ist?
Ich brauch doch trotz mangelhafter Zustände, auf die ja mit Hilfe von Exceptions aufmerksam gemacht wird, die Möglichkeit in der übergeordneten Instanz, die ja spezifische Lösungskonzepte hat, die Zustände nach übergeordneter Logik zu handeln.

Ich kenne andere Konzepte für sowas, aber wenn es doch die Möglichkeit von Haus aus gibt, wieso klappt die nicht stringent? Das will ich einfach nicht glauben :) Da gibt es doch bestimmt etwas?

Bernhard Geyer 6. Feb 2007 13:51

Re: Exception in Create-Prozedur ohne anschließendes Destroy
 
Zitat:

Zitat von robvs
das habe ich ebenfalls probiert - leider führt auch eine dort ausgelöste Exception zum Aufruf des Destructors.
Kann es sein, dass das mal eine ganz empfindliche Schwachstelle im exception handling von Delphi ist?

Finde ich nicht. Ich finde deinen Ansatz sehr komisch.
Was wäre wohl wenn z.B. du im Konstruktor eine sehr wichtige Systemresource anforderst aber nicht bekommst. Was willst du dann mit einer solch Halb-Erzeugten Instanz machen? Da ist schon besser das bei einer Exeption im Konstruktor du keinen Zeiger auf dieses Objekt bekommst und es auch wieder aufgeräumt wird.

robvs 6. Feb 2007 13:56

Re: Exception in Create-Prozedur ohne anschließendes Destroy
 
Wenn ich so eine Ressource belegte, kümmere ich mich doch auch darum. Aber das ist bei mir ja gar nicht der Fall!
Also meiner Meinung nach ist das eine "Anmaßung von Entscheidungskompetenz" seitens Delphi.

Luckie 6. Feb 2007 14:03

Re: Exception in Create-Prozedur ohne anschließendes Destroy
 
Nö. Wie willst du dich darum kümmern, wenn Methoden der Elternklasse im Konstruktor aufgerufen werden und dort eine Exception auftritt? Im gegenteil, wenn was im Konstruktor schief geht, nimmt dir Delphi alles weitere ab. Und was würdest du denn machen, wenn du im Konstrukor eine Exception bekommst und die Klasse nicht korrekt instanziert werden kann? Die Objektinstanz ist wertlos und muss wieder freigegeben werden. Und genau das macht Delphi.

Was sollte denn Delphi deiner Meinung nach machen? Dir ein kaputtes Objekt liefern, mit dem du nichts anfangen kannst? Und sowieso selber sofort wieder freigeben würdest? Und da taucht schon die nächste Frage auf: Woher weißt, du dass du nur ein kaputtes Objekt zurückbekommen hast? Die Variable ist nicht nil, aber die Klasse wurde nicht vollständig oder fehlerhaft instanziert.

Christian Seehase 6. Feb 2007 14:04

Re: Exception in Create-Prozedur ohne anschließendes Destroy
 
Moin Rob,

dann solltest Du im Konstruktor keine Exception werfen, sondern ein Flag setzen, dass Du dann als Eigenschaft veröffentlichst, in dem der Zustand der Instanz hinterlegt wird.
Dann kannst Du nach dem TMeineKlasse.Create abfragen, ob noch etwas getan werden muss oder nicht.

Zitat:

Zitat von robvs
Also meiner Meinung nach ist das eine "Anmaßung von Entscheidungskompetenz" seitens Delphi.

das kann ich nicht nachvollziehen.
Wenn das Erzeugen der Instanz fehlschlägt (Exception) existiert, normalerweise, auch keine Instanz, mit der man arbeiten könnte, also ist es nur konsequent dass aufgeräumt wird.

robvs 6. Feb 2007 14:48

Re: Exception in Create-Prozedur ohne anschließendes Destroy
 
Zuerst danke für Eure Beiträge.

Generell gehe ich da auch konform, nur in diesem Fall habe ich ein Objekt, das ich zwingend brauche, welches aber auch diverese andere Objekte direkt im Konstruktor miterzeugt. Diese können Exceptions hervorrufen und wären dann auch so weit entbehrlich, jedoch nicht mein Hauptobjekt, das weiter existieren soll. Nur wenn eine Exception in einem untergeordneten Objekt auftritt, wird auch letztendlich auch der Destruktor des Hauptobjekts aufgerufen und genau da liegt mein Problem.

Bernhard Geyer 6. Feb 2007 15:21

Re: Exception in Create-Prozedur ohne anschließendes Destroy
 
Ist doch kein Problem. Einfach den gefährlichen Teil in einem try...except kapseln und damit die Exeption selbst behandeln.

robvs 6. Feb 2007 15:25

Re: Exception in Create-Prozedur ohne anschließendes Destroy
 
Mache ich ja, aber erst in den spezifischen Modulen, die mein "Hauptobjekt" erzeugen.

Bernhard Geyer 6. Feb 2007 15:41

Re: Exception in Create-Prozedur ohne anschließendes Destroy
 
Zitat:

Zitat von robvs
Mache ich ja, aber erst in den spezifischen Modulen, die mein "Hauptobjekt" erzeugen.

Dann sollstest Du deinen Code umstellen und wie Christian angemerkt hat mit Flag arbeiten.

IngoD7 6. Feb 2007 15:45

Re: Exception in Create-Prozedur ohne anschließendes Destroy
 
Zitat:

Zitat von robvs
[...] nur in diesem Fall habe ich ein Objekt, das ich zwingend brauche, welches aber auch diverese andere Objekte direkt im Konstruktor miterzeugt. Diese können Exceptions hervorrufen und wären dann auch so weit entbehrlich, jedoch nicht mein Hauptobjekt, das weiter existieren soll. Nur wenn eine Exception in einem untergeordneten Objekt auftritt, wird auch letztendlich auch der Destruktor des Hauptobjekts aufgerufen und genau da liegt mein Problem.

Wie bereits mehrfach geschrieben: Das ist auch vernünftig so.

Aber ich habe dazu eine Frage:
Erzeugst du im Konstruktor deines "Hauptobjektes" andere, fremde, nicht zum Hauptobjekt gehörende Objekte??? Beispielsweise eine TStringliste, die sich nicht als Feld FMyStringList:TStringlist im Hauptobjekt befindet??? Das wäre doch irgendwie unschön, oder? :gruebel:

Wenn es aber alles Objekte sind, die zu deiner Hauptklasse gehören, also ein Teil ihrer sind, dann sollten die auch nicht unbedingt entbehrlich sein. Oder was verstehe ich falsch?

robvs 6. Feb 2007 16:06

Re: Exception in Create-Prozedur ohne anschließendes Destroy
 
Keine Sorge, die Objekte sind in der Klasse definiert.

Und doch kann es sein, dass es einige der Unterobj nicht gibt, da das eben Fallspezifisch ist. Es sind entbehrliche und optionale Teile, die nur unter gewissen Umständen verfügbar sind oder eben nicht. Und die Exceptions brauche ich, um im implementierenden Programm auf das Nichtvorhandensein im Einzelnen reagieren zu können. Die Zustände, ob ein Objekt existieren darf, überprüft das Objekt aber erst beim Erstellen selber, da diese Funktionalität in den Funtkionsumfang des Unterobjekts gehört.

Ich glaube, ich löse das irgendwie anders :)

Konse 20. Feb 2007 19:57

Re: Exception in Create-Prozedur ohne anschließendes Destroy
 
Hoi erstmal!!!

@robvs so eine Art Problem wie du es hast habe ich momentan auch.
In meinen Augen ist es eher ein Designproblem, wie du damit umgehen solltest, falls
eine exception im create constructor aufgerufen wird.

Denke eine Möglichkeit für dich wäre dir eine eigene Funktion keinen Konstruktor zum erstellen
zu basteln, von wo aus du deinen Konstruktor aufrufst.

schau dir einmal folgenden link an:
http://cc.codegear.com/Item/17353

für mich stellt sich eher die frage wie man so eine Exception am besten fängt.
In meinen Augen darf man dafür jedes mal für jedes Objekt (dass im Konstruktor eine Exception werfen kann)
folgendes machen:

Code:
function doSomething(const toCheck:integer):boolean;
var
lala:TCMyClass;// toCheck ist z.b. integer der nur von 5-19 gehen soll ansonsten exception
begin
  result:=false;

   try
      lala:=TCMyClass.Create(toCheck);
   except
      lala:=nil;
      exit;
   end;

   try
      lala.doWork();
   finally
     FreeAndNil(lala);
   end;
end;
Oder gibt es dafür eine elegantere Lösung, wenn man eine Exception im Konstruktor hat?


Gruß, Mario

Konse 21. Feb 2007 20:41

Re: Exception in Create-Prozedur ohne anschließendes Destroy
 
neuen thread zur frage erstellt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:21 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