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 1 von 2  1 2      
DelphiNerd84

Registriert seit: 25. Apr 2011
3 Beiträge
 
#1

Problem mit Constructor/Destructor

  Alt 25. Apr 2011, 19:58
Delphi-Version: 5
hi leute,

bin neu hier im forum und hab gleich ein problem. nach stundenlangen herumprobieren weiss ich nicht mehr weiter habe erst seit kurzem angefangen mit klassen zu arbeiten.. und scheitere bereits beim constructor bzw. dem pointer darauf.

Hier erstmal die Unit mit der Class:

Delphi-Quellcode:
UNIT UContainer;
INTERFACE
USES SysUtils;
TYPE
  TContainer=Class
    Private
      FFileName:String;
      Procedure DoSomething;
    Public
      Constructor Create(const FileName:String;AsReadOnly:Boolean);
      Destructor Destroy;override;
  End;
IMPLEMENTATION
Constructor TContainer.Create(constFName:String;AsReadOnly:Boolean);
Begin
 inherited Create;
 If FileExists(FName)Then Begin
  //HandleFile;
  //..
 End Else Destroy
End;
Destructor TContainer.Destroy;
Begin
 inherited Destroy
End;
END.
und dann..
Delphi-Quellcode:
var
  P:Pointer;
Begin
  P:=TContainer.Create('C:\Non-Existing-File.txt',False);
  If P=NIL Then
   ShowMessage('P is NIL')
  Else
   ShowMessage('P is NOT NIL');
  TContainer(P).DoSomething; //..erzeugt Exception!
End;
ich möchte also eine klasse erzeugen, die falls ein problem auftaucht (z.b. nicht existierende datei) sich gleich mittels destructor selbst zerstört. Durch aufruf des destructors sollte doch eigentlich auch der pointer darauf auf nil gesetzt werden? das passiert aber nicht! wie kann man sonst herausfinden ob die klasse noch existiert?

vielen dank!
gruss markus
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

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

AW: Problem mit Constructor/Destructor

  Alt 25. Apr 2011, 20:19
Die von dir designte Klasse ist höchst "interessant". Ich würde es so lösen:
Delphi-Quellcode:
type
  TContainer = class(TObject)
  private
    FFileName: String;
    FInvalidFile: Boolean;
  public
    procedure DoSomeThing;
    constructor Create(const FileName: String; AsReadOnly: Boolean);
    destructor Destroy;
  published
    property InvalidFile: Boolean read FInvalidFile;
  end;
Dann kannst du im Create prüfen ob die Datei geöffnet werden kann und ansonsten setzt du FInvalidFile auf true. In keinen Fall darfst du im Constructor Destroy aufrufen. Das ist tödlich
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  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
 
#3

AW: Problem mit Constructor/Destructor

  Alt 25. Apr 2011, 20:26
Destroy sollte generell nicht aufgerufen werden, sondern Free.
Im Constructor allerdings auch kein Free

Das Zerstören einer Instanz setzt die Referenzen nicht auf nil.
Darum muss man sich selber kümmern (gibt da ein Delphi-Referenz durchsuchenFreeAndNil aber das würde auch nur diese eine Referenz-Variable auf nil setzen)
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 jfheins
jfheins

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

AW: Problem mit Constructor/Destructor

  Alt 25. Apr 2011, 20:26
Auch keine gute Lösung. Denn man bekommt erstmal nichts von dem Fehler mit.

Der "best practise" Weg ist eine Exception im Konstruktor zu werfen. Wenn das passiert, wird das Objekt automatisch wieder aufgeräumt und der Ersteller bekommt eine deutliche Warnung
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

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

AW: Problem mit Constructor/Destructor

  Alt 25. Apr 2011, 21:33
Da kann man sicherlich geteilter Meinung sein. Ich persönlich mag Klassen, die in ihren Methoden Exceptions werfen absolut nicht. Ich meine normalerweise würde man folgendes machen:
Delphi-Quellcode:
var
  Container: TContainer;
begin
  Containter := TContainer.Create(FileName);
  try
    if not Container.InvalidFile then
    begin

    end;
  finally
    Container.Free;
  end;
end;
Einen spezifischen Fehlercode kann man zur not auch noch irgendwo hinterlegen.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
DelphiNerd84

Registriert seit: 25. Apr 2011
3 Beiträge
 
#6

AW: Problem mit Constructor/Destructor

  Alt 25. Apr 2011, 21:37
wow, vielen dank für die schnellen antworten! habe schon befürchtet, dass man im constructor nicht gleich wieder den destructor aufrufen darf.. wäre auch zu schön gewesen! werde wohl den code auf mehrere blöcke aufteilen müssen, ähnlich Zacherl es vorgeschlagen hat. ein problem bleibt dennoch: wie kann ich herausfinden ob eine klasse noch existiert? sir rufo sagte bereits, dass das Zerstören die Referenzen nicht auf nil setzt! somit dürfte ja folgendes beispiel NICHT funktionieren..

Delphi-Quellcode:
var
  pFolder:Array Of ^TFolder;

Procedure RemoveFolder(Index:Integer;Recurse:Boolean);
Begin
 //TFolder(pFolder[Index]).DeleteChilds...
 TFolder(pFolder[Index]).Destroy;
End;

und dann später..

Procedure UpdateListItems;
var
  i:Integer;
Begin
 For i:=0To Pred(Length(pFolder))Do
  If TFolder(pFolder[i])=NIL Then RemoveListItem
End;
..aber wie kann ich dann mittels eines Pointers der auf eine Klasse verweist herausfinden ob diese überhaupt noch existiert (ohne eine exception aufzurufen)? naja werde mich wohl oder übel eingehender mit pointer, klassen etc. beschäftigen müssen danke für eure geduld

Geändert von DelphiNerd84 (25. Apr 2011 um 21:40 Uhr)
  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
 
#7

AW: Problem mit Constructor/Destructor

  Alt 25. Apr 2011, 21:42
Du könntest aber auch eine class function bemühen, die dir ein entsprechendes Objekt zurückliefest oder eben nicht (nil)
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
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.851 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: Problem mit Constructor/Destructor

  Alt 25. Apr 2011, 21:43
Dann halt statt
Delphi-Quellcode:
  finally
    Container.Free;
  end;
Delphi-Quellcode:
  finally
    FreeAndNil( Container);
  end;
Btw nie Destroy direkt aufrufen
Zudem würde ich statt eines arrays eine Liste verwenden
Markus Kinzler
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

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

AW: Problem mit Constructor/Destructor

  Alt 25. Apr 2011, 22:10
Da kann man sicherlich geteilter Meinung sein. Ich persönlich mag Klassen, die in ihren Methoden Exceptions werfen absolut nicht. Ich meine normalerweise würde man folgendes machen:
Delphi-Quellcode:
var
  Container: TContainer;
begin
  Containter := TContainer.Create(FileName);
  try
    if not Container.InvalidFile then
    begin

    end;
  finally
    Container.Free;
  end;
end;
Einen spezifischen Fehlercode kann man zur not auch noch irgendwo hinterlegen.
OMG

Zuerst zu dem Fehlercode: Das läuft auf das Gleiche hinaus wie die Property. Man kann sie ignorieren. Und das ist nicht gut. Unter anderem aus diesem Grund gibt es ja gerade die Exceptions, damit nicht jede Klasse ihren eigenen Fehlermechanismus implementieren muss.

Das zweite: Man lässt den Code einfach mal laufen und guckt dann nachher, ob es einen Fehler gegeben hat. Warum nicht vorher prüfen?

Delphi-Quellcode:
var
  Container: TContainer;
begin
   if Fileexists(FileName) then
   begin
      Containter := TContainer.Create(FileName);
      try
         //Was machen
      finally
         Container.Free;
      end;
   end;
end;
Falls die Prüfung vorher tatsächlich nicht gewünscht ist, geht immer noch das hier:
Delphi-Quellcode:
try
   Containter := TContainer.Create(FileName);
except end;

  If Containter=NIL Then
    ShowMessage('Containter is NIL')
   Else
    ShowMessage('Containter is NOT NIL');
   Containter.DoSomething; //..erzeugt Exception!
Wenn der Konstruktor eine Exception wirft, wird die Variable nicht verändert - bleibt also nil.
Der Zugriff am Ende erzeugt aber immer noch eine AV.
  Mit Zitat antworten Zitat
DelphiNerd84

Registriert seit: 25. Apr 2011
3 Beiträge
 
#10

AW: Problem mit Constructor/Destructor

  Alt 25. Apr 2011, 22:59
es funzt! keine ahnung ob des professionell gelöst ist, aber es geht erstmal

Delphi-Quellcode:
UNIT UContainer;
INTERFACE
USES
  SysUtils;
VAR
  pSelf:Pointer;
TYPE
  TContainer=Class
    Private
      FFileName:String;
      //pLevel:Arary Of ^TLevel;
      //Procedure HandleFile;
      //..
    Public
      Class Function Alive:Boolean;
      Constructor Create;
      Destructor Destroy;override;
      Procedure Assign(const FName:String;AsReadOnly:Boolean);
      Property FileName:String Read FFileName;
      //..
  End;
IMPLEMENTATION
Class Function TContainer.Alive:Boolean;
Begin
 Result:=pSelf<>NIL
End;
Constructor TContainer.Create;
Begin
 inherited Create;
 pSelf:=Pointer(Self);
 //..
End;
Destructor TContainer.Destroy;
Begin
 //..
 pSelf:=NIL;
 inherited Destroy
End;
Procedure TContainer.Assign(const FName:String;AsReadOnly:Boolean);
Begin
 If Not FileExists(FName)Then Begin
  //Destroy
  Free
 End
End;
END.
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;
Danke an alle! und gute n8

Geändert von DelphiNerd84 (25. Apr 2011 um 23:20 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 20: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