AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Problem mit Constructor/Destructor

Ein Thema von DelphiNerd84 · begonnen am 25. Apr 2011 · letzter Beitrag vom 26. Apr 2011
Antwort Antwort
Seite 2 von 2     12   
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#11

AW: Problem mit Constructor/Destructor

  Alt 26. Apr 2011, 00:06
Wie gesagt Geschmackssache. Angenommen die Prüfung gestaltet sich nicht so einfach, wie das Prüfen auf Vorhandensein einer Datei. Eine Exception wird im Constructor geworfen. Dann sieht der Quelltext schon extrem unübersichtlich aus:

Delphi-Quellcode:
var
  Container: TContainer;
begin
  try
    Containter := TContainer.Create(FileName);
    try
      // Hier mache ich was
    finally
      Container.Free;
    end;
  except
    // Hier ging was schief
  end;
end;
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#12

AW: Problem mit Constructor/Destructor

  Alt 26. Apr 2011, 11:36
Okay, es kommt darauf an, ob die Klasse ohne Datei noch etwas leistet. nehmen wir als beispiel TFileStream. Wenn man den initialisiert, und eine ungültige Datei angibt (und das Flag so gesetzt ist, dass er eine erwartet) dann wirft das Ding eine FileNotFound Exception. Denn ohne Datei macht ein Filestream keinen Sinn.

Es ist Aufgabe des aufrufenden Codes, sicherzustellen dass das nicht passiert. Wenn der Filestream zum speichern benutzt wird, ist vermutlich fmCreate gesetzt. Beim Laden ist der Opendialog vermutlich so eingestellt dass er nur vorhandene Dateien zurückliefert. Beide Fälle vermeiden also im Normalfall die Exception wie es sein sollte, nur im Ausnahmefall gibt es sie dann halt doch.

Wenn die TContainer-Klasse ohne Datei keinen Nutzen hat, ist es nur korrekt, dass dann eine Exception geworfen wird wenn es diese Datei nicht gibt. Denn wenn ein Fehler erkannt wurde sollte dieser so früh wie möglich "gemeldet" werden. Das erleichtert die Fehlersuche ungemein

Wenn die TContainer-Klasse auch ohne gültige Datei einen Nutzen hat, sollte der Dateiname in eine Property ausgelagert werden. (Optional ein überladener Konstruktor der einen dateinamen entgegennimmt.)

Im Konstruktor eine Prüfung einzubauen, und das Objekt ggf. wieder zu zerstören empfinde ich als grottenschlechten Programmierstil. Schon bei dem Standardkonstrukt
Delphi-Quellcode:
var
  Container: TContainer;
begin
    Containter := TContainer.Create(FileName);
    try
      // Hier mache ich was
    finally
      Container.Free;
    end;
end;
bekommt man eine AV und weiß nicht warum.

Die "Lösung" aus Post #10 könnte man direkt als Gegenbeispiel für guten Code verwenden. Im speziellen stört mich:
Eine globale Variable pSelf bestimmt das Verhalten des Objekts, man darf anscheinend keine 2 Objekte direkt hintereinander erstellen, sonst zerschießt man den Mechanismus komplett - OMG.
Es wird zwar der Name "Assign" benutzt, aber nicht für den Zweck den es sonst erfüllt.
Man muss nachher das Objekt fragen, ob es einen Fehler gefunden hat und muss dann ggf. seine Variable selber wieder nil setzen.

Ganz ehrlich - die einzige Möglichkeit, diesen Code noch schlimmer zu machen ist ein goto.
@Zacherl: das ist vielleicht ein bisschen unübersichtlich, weil da 2 try-Blöcke vorkommen. Aber wenn man sich das genauer anguckt merkt man schnell, was passiert. Und welcher Code wann ausgeführt wird.
Da ist der Code
Delphi-Quellcode:
var
  P:Pointer;
Begin
 P:=TContainer.Create;
 TContainer(P).Assign('C:\Non-Existing-File.txt',False);
 If NOT TContainer(P).Alive Then Begin
  ShowMessage('Klasse existiert nicht mehr!');
  P:=NIL
 End
End;
zwar "flacher" von der Einrückung her, aber warum man jetzt das eine oder andere macht wird nicht deutlich. Der Code hat weniger Struktur.

Ich sehe hier ein Problem das durch Exceptions hervorragend gelöst werden kann und wundere mich etwas, dass so eine Krücke geschrieben wird, um Exceptionhandling zu vermeiden. Hängt möglicherweise auch mit Unwissenheit (seitens des TE) zusammen, deshalb bin ich gerne Bereit das ganze ein bisschen mehr zu erklären, wenn das gewünscht wird

Btw.: Willkommen in der DelphiPRAXiS
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#13

AW: Problem mit Constructor/Destructor

  Alt 26. Apr 2011, 12:46
ich hatte das eigentlich so gedacht:
Delphi-Quellcode:
UNIT UContainer;

INTERFACE

USES
  SysUtils;

TYPE
  TContainer=Class
    Private
      FFileName:String;
    Public
      class function Build(const FName:String;AsReadOnly:Boolean) : TContainer;
      Constructor Create(const FName:String;AsReadOnly:Boolean);
      Destructor Destroy;override;
      Property FileName:String Read FFileName;
  End;

IMPLEMENTATION

class function TContainer.Build(const FName:String;AsReadOnly:Boolean) : TContainer;
begin
  if FileExists( FName ) then
    Result := TContainer.Create( FName, AsReadOnly )
  else
    Result := nil;
end;

Constructor TContainer.Create(const FName:String;AsReadOnly:Boolean);
Begin
 inherited Create;
  FFileName := FName;
  // ...
End;

Destructor TContainer.Destroy;
Begin

 inherited Destroy
End;

END.
Aufruf:
Delphi-Quellcode:
var
  Container : TContainer;
begin
  Container := TContainer.Build( 'foo.txt', False );
  if Assigned( Container ) then
  begin
    
  end;
end;
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#14

AW: Problem mit Constructor/Destructor

  Alt 26. Apr 2011, 13:20
Wozu eigentlich das Rumgecaste mit dem Pointer?

Vorallem für Anfänger wäre das nicht zu empfehlen, da man sich dadurch schnell mal Fehler und unnötige Probleme einhandeln kann.
$2B or not $2B
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


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 09:25 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