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 Member Class löschen (https://www.delphipraxis.net/181231-member-class-loeschen.html)

hanspeter 28. Jul 2014 08:31

Delphi-Version: XE2

Member Class löschen
 
Hallo,
Mit einem Record ist das ja kein Problem.
Delphi-Quellcode:
datRec = record
 p1: string;
 p2: integer;
end;

var
 x: Datrec;

fillchar(x,sizeof(x),0);
Den Code will ich in einem alten Programm mit einer Klasse ersetzen.
Als Möglichkeit fällt mir im Moment ein
- die Klasse freizugeben und neu zu erzeugen.
- Ein Vorfahre der über RTTI alls Member auf null setzt.
- Eine Methode Clear, die alle Member auf Null setzt.

Fällt jemanden noch eine weitere Variante ein?

Uwe Raabe 28. Jul 2014 08:42

AW: Member Class löschen
 
InitInstance?

Aber das kann auch schon mal ins Auge gehen, wenn Ableitungen von der Klasse nicht damit rechnen...

hanspeter 28. Jul 2014 08:52

AW: Member Class löschen
 
Ist aber unsicher?
Zitat:
Da InitInstance keine virtuelle Methode ist, können Sie sie nicht überschreiben: Initialisieren Sie daher alle Daten eines Objekts im Konstruktor.

Stevie 28. Jul 2014 08:57

AW: Member Class löschen
 
FillChar wird bei records doch meistens eh nur benutzt, um eine lokale Variable zu initialisieren. Das ist bei einer Klasse nicht notwendig.

Uwe Raabe 28. Jul 2014 09:08

AW: Member Class löschen
 
Wenn ich das richtig verstanden habe, will er eine bereits instanzierte Klasse wieder reseten - und das mit einer einzigen Methode, wie für alle denkbaren Klassen funktioniert. Wegen der möglichen Komplexität, die manche Klassen an den Tag legen, ist das aber meiner Meinung nach zum Scheitern verurteilt.

Insofern möchte ich meinen Vorschlag von
Delphi-Quellcode:
InitInstance
auch lieber zurückziehen. Es tut zwar im wörtlichen Sinne was gewünscht ist, aber in vielen Fällen ist dieses Verhalten eigentlich gar nicht erwünscht bzw. das Ergebnis dann unerwartet.

Entweder man schreibt eine passende Methode
Delphi-Quellcode:
Clear
für jede Klasse oder man erzeugt die Klasse neu. Das ist auf jeden Fall der sicherere Weg.

Stevie 28. Jul 2014 09:17

AW: Member Class löschen
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1266779)
Wenn ich das richtig verstanden habe, will er eine bereits instanzierte Klasse wieder reseten - und das mit einer einzigen Methode, wie für alle denkbaren Klassen funktioniert. Wegen der möglichen Komplexität, die manche Klassen an den Tag legen, ist das aber meiner Meinung nach zum Scheitern verurteilt.

Insofern möchte ich meinen Vorschlag von
Delphi-Quellcode:
InitInstance
auch lieber zurückziehen. Es tut zwar im wörtlichen Sinne was gewünscht ist, aber in vielen Fällen ist dieses Verhalten eigentlich gar nicht erwünscht bzw. das Ergebnis dann unerwartet.

Entweder man schreibt eine passende Methode
Delphi-Quellcode:
Clear
für jede Klasse oder man erzeugt die Klasse neu. Das ist auf jeden Fall der sicherere Weg.

Dem kann ich nur zustimmen.

hanspeter 28. Jul 2014 09:33

AW: Member Class löschen
 
Das ist wie gesagt ein Legacy Projekt, was ich auf Unicode umstelle.
Der Record wird einmal (local) angelegt und dann beliebig oft gelöscht und mit neuen Daten gefüllt.
Bisher habe ich schon (fast) jede Klasse mit einer Assign und einer Clear Methode ergänzt.
Ist zwar Copy und Paste der Variablenliste aber es nervt.
Ich hatte die Hoffnung das ich noch eine Möglichkeit übersehen habe, das eleganter zu lösen.
Also erst mal vielen Dank.

himitsu 28. Jul 2014 10:48

AW: Member Class löschen
 
Zitat:

Zitat von hanspeter (Beitrag 1266773)
Mit einem Record ist das ja kein Problem.
Delphi-Quellcode:
datRec = record
 p1: string;
 p2: integer;
end;

var
 x: Datrec;

fillchar(x,sizeof(x),0);

Und schon hast du ein Speicherleck, da du die Referenzzählung des Strings zerschießt. (wenn in p1 etwas drin war)

Einzige ordentliche Lösung: die Clear-Methode

smallie 28. Jul 2014 11:59

AW: Member Class löschen
 
Wie wär's damit, den constructor auf die Instanz anzuwenden?

Sieht zwar ungewohnt aus, hat aber den Vorteil, die Vererbungshierarchie zu berücksichtigen.

Delphi-Quellcode:
type
  TClearingClass = class
  private
  public
    s: string;
    i: integer;
    constructor create;
  end;

  TClearingChild = class(TClearingClass)
  public
    d: double;
    constructor create;
  end;

implementation

{ TClearingClass }

constructor TClearingClass.create;
begin
  inherited;
  // explizit:
  s := '';
  i := 0;
end;

{ TClearingChild }

constructor TClearingChild.create;
begin
  inherited;
  d := 0.0;
end;

Beispiel:

Delphi-Quellcode:
type

  TForm1 = class(TForm)
    btnCreate: TSpeedButton;
    btnInit: TSpeedButton;
    procedure btnCreateClick(Sender: TObject);
    procedure btnInitClick(Sender: TObject);
  private
  public
  end;

implementation

procedure TForm1.btnCreateClick(Sender: TObject);
begin
  ClearingChild := TClearingChild.create; //Constructor
  showMessageFmt('s: %s, i: %d, d: %g',
    [ClearingChild.s, ClearingChild.i, ClearingChild.d]);  //s: , i: 0, d: 0

end;

procedure TForm1.btnInitClick(Sender: TObject);
begin
  ClearingChild.s := 'changed';
  ClearingChild.i := -1;
  ClearingChild.d := -1.1;
  ClearingChild.create; //Instanz initialisieren
  showMessageFmt('s: %s, i: %d, d: %g',
    [ClearingChild.s, ClearingChild.i, ClearingChild.d]);  //s: , i: 0, d: 0
end;

Stevie 28. Jul 2014 12:54

AW: Member Class löschen
 
Zitat:

Zitat von smallie (Beitrag 1266795)
Wie wär's damit, den constructor auf die Instanz anzuwenden?

Davon möchte ich dringend abraten. Außer, dass es schlechter Stil ist, den Konstructor als Clear Methode zu missbrauchen,
wird dieser Code auch u.U. mit einem Compiler Fehler quittiert.


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