AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Behandlung von Exceptions innerhalb von Konstruktoren
Thema durchsuchen
Ansicht
Themen-Optionen

Behandlung von Exceptions innerhalb von Konstruktoren

Ein Thema von MatthiasR · begonnen am 17. Sep 2007 · letzter Beitrag vom 18. Sep 2007
Antwort Antwort
MatthiasR

Registriert seit: 21. Apr 2005
193 Beiträge
 
#1

Behandlung von Exceptions innerhalb von Konstruktoren

  Alt 17. Sep 2007, 16:45
Hallo allerseits,

ich habe mir schon oft die Frage gestellt, wie man eigentlich korrekterweise mit Exceptions innerhalb von Konstruktoren selbstgeschriebener Klassen umgeht. Als Beispiel habe ich mal ein kleines Mini-Programm entworfen mit einer selbstdefinierten Klasse (von TObject abgeleitet) und einem eigenen Konstruktor, in der nichts weiter gemacht wird, als eine Exception ausgelöst. Aber schaut es euch selber an:
Delphi-Quellcode:
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

type
  TMyClass = class(TObject)
  private
  public
    constructor Create(bCreateException: Boolean);
end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TMyClass }

constructor TMyClass.Create(bCreateException: Boolean);
begin
  inherited Create;
  if bCreateException then
    raise Exception.Create('Test');
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  MyObject : TMyClass;
begin
  try
    MyObject := TMyClass.Create(True);
  except
    if Assigned(MyObject) then
      FreeAndNil(MyObject);
  end;
end;
In der ButtonClick-Routine wird ein Objekt der Klasse TMyClass erzeugt, in deren Konstruktor bereits eine Exception auftritt.

Nun meine Frage: Wird durch das "inherited Create" innerhalb des Konstruktors bereits Speicher allokiert (ja oder?) und wie gebe ich den dann anschließend frei??? Die Funktion "Assigned(MyObject)" liefert True zurück, das FreeAnNil anschließend erzeugt jedoch eine Speicherzugriffsverletzung.

Oder sind Exceptions innerhalb von Konstruktoren so ein typischen Unding, was man nie nie nie nie [...] nie nie niemals bei Delphi machen sollte ?

Vielen Dank im Voraus für die Hilfe!
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#2

Re: Behandlung von Exceptions innerhalb von Konstruktoren

  Alt 17. Sep 2007, 17:02
Delphi packt ein try-except um die Konstruktoren, sodass bei einer Exception automatisch alles wieder freigegeben und destroy aufgerufen wird.
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#3

Re: Behandlung von Exceptions innerhalb von Konstruktoren

  Alt 17. Sep 2007, 17:22
Zu dem Code noch zwei Anmerkungen:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  MyObject : TMyClass;
begin
  try
    MyObject := TMyClass.Create(True);
  except
    if Assigned(MyObject) then
      FreeAndNil(MyObject);
  end;
end;
1. Das If Assigned() kannst du dir sparen, das macht .Free intern selber (welches durch FreeAndNil() aufgerufen wird).
2. Ohne Initialisierung der Variable auf nil, knallt es so oder so, da das eine lokale Variable ist welche nicht initialisiert ist und somit ist die Möglichkeit eines recht ungültigen Wertes hoch. Dagegen kann auch Assigned() nichts ausrichten, da es nur auf <> nil prüft...

Und da du nicht freigeben brauchst, wie zuvor erklärt, kannst du dir somit gleich viel mehr sparen:

Somit so:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  MyObject : TMyClass;
begin
  try
    MyObject := TMyClass.Create(True);
  except
    ShowMessage('Problem beim anlegen der Instanz');
  end;
end;
  Mit Zitat antworten Zitat
r2c2

Registriert seit: 9. Mai 2005
Ort: Nordbaden
925 Beiträge
 
#4

Re: Behandlung von Exceptions innerhalb von Konstruktoren

  Alt 17. Sep 2007, 18:25
Um das mit den Konstruktoren nochmal klar zu stellen. IMHO ist es noch nicht ganz so klar beschieben:
- Create immer vor das try:
Delphi-Quellcode:
var
  test: TTest;
begin
  test := TTest.Create;
  try
    try
      test.DoSth(...);
    except
      ShowMessage('Die Welt geht gleich unter...');
    end;
  finally
    test.Free; // von mir aus auch FreeAndNil(), aber das ist hier nicht nötig, da die Variable beim Verlassen des Gültigkeitsbereiches ja eh im Nirwana verschwindet
  end;
end;
- Alternative: vorher nillen(insbesondere praktisch, wenn man mehrere Objekte hat):
Delphi-Quellcode:
var
  test: TTest;
begin
  test := nil;
  try
    try
      test := TTest.Create;
      test.DoSth(...);
    except
      ShowMessage('Die Welt geht gleich unter...');
    end;
  finally
    test.Free; // von mir aus auch FreeAndNil(), aber das ist hier nicht nötig, da die Variable beim Verlassen des Gültigkeitsbereiches ja eh im Nirwana verschwindet
  end;
- Wenn im Konstruktor eine Exception auftritt, kümmert sich Delphi darum, dass die schon reservierten ressourcen wieder freigegeben werden(siehe Muetzes Post)
- Will man auf eine im Konstruktor geworfene Exception reagieren, so nimmt man am besten die 2. oben genannte Variante.
- Alternativ kann man auch einen weiteren try...except Block ganz außen drum herum bauen, muss aber dann drauf achten, dass man dort auf das Objekt nicht mehr zugreifen kann...

mfg

Christian
Kaum macht man's richtig, schon klappts!
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#5

Re: Behandlung von Exceptions innerhalb von Konstruktoren

  Alt 17. Sep 2007, 19:12
oder so:
Delphi-Quellcode:
var
  test: TTest;
begin
  try
    test := TTest.Create();
    try
      //do anything with the objectinstance of test
    except
      ShowMessage('Fehler beim hantieren mit dem Object.');
    end;
    test.Free;
  except
    ShowMessage('Fehler beim erzeugen des Objectes.');
  end;
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#6

Re: Behandlung von Exceptions innerhalb von Konstruktoren

  Alt 17. Sep 2007, 20:03
Die letzte Meldung sollte wohl eher heissen: "Fehler beim Erzeugen oder Freigeben des Objectes."
  Mit Zitat antworten Zitat
MatthiasR

Registriert seit: 21. Apr 2005
193 Beiträge
 
#7

Re: Behandlung von Exceptions innerhalb von Konstruktoren

  Alt 18. Sep 2007, 10:49
OK, ich verstehe, erstmal danke für ausführliche die Hilfe !

Wäre denn auch folgender Aufbau sinnvoll (so würde ich es dann machen wollen):
Delphi-Quellcode:
procedure TForm1.TuWas;
var
  Test: TTest;
begin
  try
    Test := TTest.Create();
    try
      // Irgendwas mit Test anstellen
    finally
      FreeAndNil(Test); // habe mir eben FreeAndNil angewöhnt ;)
    end;
  except
    ShowMessage('Es trat in Prozedur "TuWas" ein Fehler auf.');
  end;
end;
  Mit Zitat antworten Zitat
r2c2

Registriert seit: 9. Mai 2005
Ort: Nordbaden
925 Beiträge
 
#8

Re: Behandlung von Exceptions innerhalb von Konstruktoren

  Alt 18. Sep 2007, 12:48
Jo, is IMHO OK so...

mfg

Christian
Kaum macht man's richtig, schon klappts!
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:19 Uhr.
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