Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Create abbrechen (https://www.delphipraxis.net/92039-create-abbrechen.html)

Masterj44 13. Mai 2007 18:52


Create abbrechen
 
Hi Leute,
hab da mal ne Frage

Kann man ein Create abbrechen?

Also ich habe ein Create Methode, die sich bei bestimmten Voraussetzungen selbst mit self.destroy zerstört.

Frage:
1. Ist es so möglich die Instanz zu löschen?
2. Wenn ja, wieso gib die varible die auf die Instanz zeigt nicht nil?

GuenterS 13. Mai 2007 19:10

Re: Create abbrechen
 
Weil Destroy nur das Objekt freigibt und nicht auf Nil setzt. Verwende anstelle dessen doch FreeAndNil.

mkinzler 13. Mai 2007 19:12

Re: Create abbrechen
 
Aber vielleicht wäre es besser es erst garn icht zu erzeugen

Masterj44 13. Mai 2007 19:19

Re: Create abbrechen
 
@ GuenterS FreeandNil klapt nicht da es mit self.destroy zerstört werden muss

Anders geht es leider nicht. Als ich brauch nur eine Methode die mir sagt, dass die Erzeugung des Objekts nicht geklappt hat.

Christian Seehase 13. Mai 2007 19:23

Re: Create abbrechen
 
Moin Master,

wenn sich im Konstruktor eine Konstellation ergibt, die die Instanzierung sinnlos machen könntest Du einfach eine Exception auslösen, so dass die Stelle, die den Konstruktor aufgerufen hat darauf reagieren kann.


Delphi-Quellcode:
type
  TMyClass = class(TObject)
  public
    constructor Create;
  end;

procedure IrgendEine;

var
  tmc : TMyClass;

begin
  try
    tmc := TMyClass.Create;
    try
      // Tu was mit der Instanz
    finally
      FreeAnNil(tmc);
    end;
  except
    // Hier eine passende Meldung ausgeben
  end;
end;

constructor TMyClass.Create;
begin
  inherited;
  if FalscheVoraussetzung then raise Exception.Create('Fehler');
end;

Elvis 13. Mai 2007 20:03

Re: Create abbrechen
 
Zitat:

Zitat von Christian Seehase
wenn sich im Konstruktor eine Konstellation ergibt, die die Instanzierung sinnlos machen könntest Du einfach eine Exception auslösen, so dass die Stelle, die den Konstruktor aufgerufen hat darauf reagieren kann.

Eine Ausnahme im Konstruktor sollte schon zum Freigeben des Objektes führen. Doppeltes Freigeben ist nicht so nett.
Das ist auch der Grund, warum man das Instanzieren vor den berühmt-berüchtigten try-finally-free-Block schreibt.

alzaimar 13. Mai 2007 20:05

Re: Create abbrechen
 
Meiner Meinung nach sollte man keine Konsistenzprüfung in einem Konstruktor vornehmen. Das ist zwar Geschmackssache, aber in meinen Augen durchaus sinnvoll: Beim Erstellen einer Instanz weiss ich noch gar nicht, ob sie später mal konsistenz ist oder nicht (gemäß der Theorie).

Entweder implementiere ich das in einer Class Function und rufe die VOR der Instantiierung auf (praktisch, aber uncool), oder ich prüfe die Konsiszenz über eine stinknormale Methode, die die Eigenschaften, die ich ja (reine Lehre) erst zuweisen muss, naturgemäß bei der Instantiierung noch nicht bekannt sind.

In seltenen Fällen (siehe TFileStream) kann es aber durchaus Sinn machen (bzw. die Tipparbeit erheblich verkürzen und zu lesbarerem Code führen), Eigenschaften in einem Konstruktor zu übergeben und eine Prüfung während der Instantiierung vorzunehmen. Dann wird eine Exception ausgelöst, wie es hier auch schon erwähnt wurde. Es wird -soweit ich weiss- kein Speicher alloziiert, sodaß die Instanz auch nicht freigegeben werden muss.

Jelly 13. Mai 2007 20:07

Re: Create abbrechen
 
Wie Chris schon schrieb, so würd ich das auch lösen. Anstatt einer einfachen Exception würd ich eventuell eine Assertion auslösen. Denn genau dafür sind die da.

Das ist ein typisches Beispiel. Im Construtor der Klasse müssen gewisse Bedingungen erfüllt sein, damit die Klasse überhaupt Sinn macht. z.B. wenn ein Datensatz aus einem Dataset in einer Klasse abgebildet werden soll, so empfiehlt es sich, im constructor den Primary Key des Datensatz anzugeben. Gibt es den nicht, macht eine Instanz eventuell keinen Sinn.

Eine Assertion ist eine Art von exception, die Dir aber bequemerweise aber in der Fehlermeldung auch gleich noch die Zeilennummer in deinem Code ausgibt, in der die Assertion ausgelöst wurde.

Elvis 13. Mai 2007 20:23

Re: Create abbrechen
 
Zitat:

Zitat von alzaimar
Meiner Meinung nach sollte man keine Konsistenzprüfung in einem Konstruktor vornehmen. Das ist zwar Geschmackssache, aber in meinen Augen durchaus sinnvoll: Beim Erstellen einer Instanz weiss ich noch gar nicht, ob sie später mal konsistenz ist oder nicht (gemäß der Theorie).

Jain.

Für stinknormale Klassen, die transiente oder persistente Daten deines Applikationsmodelles halten mag das zutreffen.
Aber es wird immer wieder Klassen geben, die sich immer in einem konsistenten Zustand befinden müssen.
Ein FileStream wäre so ein Fall.

Zitat:

Entweder implementiere ich das in einer Class Function und rufe die VOR der Instantiierung auf (praktisch, aber uncool)...
Klassische Factory, IMHO sogar sehr cool, da de Prüfung vor dem Allozieren von Speicher passieren kann.
Zitat:

, oder ich prüfe die Konsiszenz über eine stinknormale Methode, die die Eigenschaften, die ich ja (reine Lehre) erst zuweisen muss, naturgemäß bei der Instantiierung noch nicht bekannt sind.
Das Zuweisen einzelnener Eigenschaften lässt es aber nicht zu einen konsistenten Zustand zu garantieren.
Änder ich Eigenschaft1 zu "X" wäre meine Instanz vllt ouchy banana und der Setter springt mir ins Gesicht.
Er kann ja nicht wissen, dass ich Eigenschaft2 direkt danach auch "Y" ändern wollte.
Ein Konstruktor, dem beide Werte übergeben werden, und der sie in einer "Transaktion" ändern kann ist hier natürlich vorteilhaft.
Genau wie es oben genannte Factory wäre.
Zitat:

In seltenen Fällen (siehe TFileStream) kann es aber durchaus Sinn machen (bzw. die Tipparbeit erheblich verkürzen und zu lesbarerem Code führen), Eigenschaften in einem Konstruktor zu übergeben und eine Prüfung während der Instantiierung vorzunehmen.
Selten ist Tipparbeit, sondern Konsistenz die Motivation dahinter.
Zitat:

Dann wird eine Exception ausgelöst, wie es hier auch schon erwähnt wurde. Es wird -soweit ich weiss- kein Speicher alloziiert, sodaß die Instanz auch nicht freigegeben werden muss.
Der Konstruktor wird nach NewInstance ausgeführt, also nachdem Speicher reserviert wurde.
In der Kette der einzelnen Calls, die irgendwann zu einer fertigen Instanz führen, wird aber beim Auftreten einer Exception die neue Instanz sofort freigegeben.


Zitat:

Zitat von Jelly
Wie Chris schon schrieb, so würd ich das auch lösen. Anstatt einer einfachen Exception würd ich eventuell eine Assertion auslösen. Denn genau dafür sind die da.
...
Eine Assertion ist eine Art von exception, die Dir aber bequemerweise aber in der Fehlermeldung auch gleich noch die Zeilennummer in deinem Code ausgibt, in der die Assertion ausgelöst wurde.

Au weia.
Assertions sind dafür da deinen Code zu prüfen. Niemals um Dinge zu prüfen, die von außen/ von Benutzern deiner Klasse rein geworfen wurden.
Denn Assertions werden normalerweise im Release ausgeschaltet.

DGL-luke 13. Mai 2007 20:26

Re: Create abbrechen
 
eine assertion so wie "assert(boolean, string)"?

wird die nicht im final build deaktiviert?

//wie elvis sagte.


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:04 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz