Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Klassen: Clear -> Free -> Create? (https://www.delphipraxis.net/205672-klassen-clear-free-create.html)

Benmik 4. Okt 2020 22:50

Klassen: Clear -> Free -> Create?
 
Ich habe eine Klasse mit ziemlich vielen Feldern, die ich bei einem
Delphi-Quellcode:
Clear
alle händisch zurücksetzen müsste.
Da liegt es nahe, einfach im
Delphi-Quellcode:
Clear
ein
Delphi-Quellcode:
Free
und danach ein
Delphi-Quellcode:
Create
zu schreiben.
Das Free klappt auch, aber wenn ich danach
Delphi-Quellcode:
Self := TDingsbums.Create
schreibe, dann meint der Compiler, "Self" würde nie benutzt.

Spaßeshalber habe ich mal versucht, eine Instanz einfach in einer ihrer Methoden freizugeben und wieder zu erzeugen. Also ungefähr so:
Delphi-Quellcode:
TCorona = class(TObject)
  procedure VirusBeißtZu;
end;

var Corona:TCorona;

...

procedure TCorona.VirusBeißtZu;
begin
  Corona.Free;
  Corona := TCorona.Create;
end;
Zu meinem Erstaunen scheint das zu funktionieren.

Was ist von alledem zu halten?

stahli 4. Okt 2020 23:47

AW: Klassen: Clear -> Free -> Create?
 
Es ist eigentlich ganz einfach.

Du hast eine globale Variable, der Du letztlich eine neu erzeugte Instanz zuweist.
Insofern nichts besonderes.

Die Prozedur hast Du allerdings als Methode angelegt.
Insofern muss erst mal eine Instanz erzeugen damit Du die Methode korrekt ausführen kannst.

Du könntest die Methode alternativ als Klassenmethode (class procedure ...) anlegen, damit Du sie immer aufrufen kannst.
Oder Du erzeugst einfach eine ganz normale Prozedur (nicht als Teil einer Klasse), in der Du die neue Instanz erzeugst und zuweist.

Du kannst damit halt immer nur eine globale Variable neu zuweisen.

Du könntest auch eine Prozedur erstellen und eine Variable als var-Parameter übergeben und dieser eine neue Instanz zuweisen.


Da gibt es unterschiedliche Möglichkeiten - ABER ...
... die Klasseneigenschaften einfach in einer Methode "Clear" aufzuräumen ist m.E. der beste Weg.

Die anderen Lösungen empfinde ich als unnötig komplitziert und unübersichtlich. Für das Zurücksetzen von Eigenschaften bietet sich eine Methode Clear oder Init doch nahezu an.

himitsu 4. Okt 2020 23:59

AW: Klassen: Clear -> Free -> Create?
 
Self ist nur ein interner einfacher Parameter, der keine Referenz auf die externe Variable besitzt, daher ist das so nicht möglich.


Delphi-Quellcode:
procedure TCorona.VirusBeißtZu(Self: TCorona); // intern ist das Self
begin
  Self.Free;
  Self := TCorona.Create;
end;

//Corona.VirusBeißtZu;
TCorona.VirusBeißtZu(Corona);
Und "leider" ist es nicht möglich die Übergabe zu beeinflussen,
drum ist FreeAndNil auch eine Prozedur und kann micht ebenfalls als Methode implementiert werden, so wie das Free.

Man könnte jetzt in das Speichermanagement eingreifen und nach dem Free das neue Objekt an der "selben" Speicheradresse erzeugen.
Da dann beide Objekte an der selben Stelle liegen, zeigt die externe Variable immernoch auf die "richtige" Stelle.
Bei Multithread kann es aber schief geh.

Dann gäbe es noch die RTTI, mit welcher man alle Felder durchlaufen und freigeben könnte.

Oder man verschiebt die Daten.
Delphi-Quellcode:
type
  TFoo = class(TObject)
    FData: record
      i: Integer;
      S: string;
      A: TArray<Integer>;
    end;
    procedure Clear;
  end;

procedure TFoo.Clear;
begin
  Finalize(FData);
  FillChar(FData, SizeOf(FData), 0); // oder ZeroMemory(@FData, SizeOf(FData)); ... was man halt mag
end;

// oder besser
procedure TFoo.Clear;
begin
  Finalize(FData); // gibt nur den Inhalt frei, z.B. von Strings, aber ohne die Variable selbst zurückzusetzen.
  FillChar(FData, SizeOf(FData), 0);
  Initialize(FData); // Initialisiert nur gemanagte Typen mit 0, also Strings, Variants, dynamische Array, gen. Methoden-Zeiger und IInterface, daher vorher das FillChar/ZeroMemory
end;
bzw.
FinalizeRecord aka FinalizeArray mit Lenght=1
und
InitializeRecord aka InitializeArray mit Lenght=1

Das sind auch die Methoden, welche Delphi benutzt, um globale Variablen, lokale Variablen (das was im BEGIN und END der Methode aufgerufen wird) und den Inahlt von Objekten zu initialisieren und freizugeben.

haentschman 5. Okt 2020 05:24

AW: Klassen: Clear -> Free -> Create?
 
Moin...:P
Die eigentliche Frage ist nicht beantwortet...
Zitat:

Was ist von alledem zu halten?
...nichts! :warn: Das das funktioniert ist eher Zufall :? Instanzen die in "Benutzung" sind, Pointer in Listen (die ihre Objekte selbst freigeben), sind sind nicht mehr gültig, weil der Pointer ein anderer und der vorhergehende freigeben ist. Dann dürfte es Zugriffsverletzungen hageln...:roll:
Wenn mir ein simpler Vergleich einfällt, lasse ich es euch wissen...:zwinker:

Jumpy 5. Okt 2020 08:59

AW: Klassen: Clear -> Free -> Create?
 
[Offtopic]
Wenn der Baron von Münchhausen eine solche Phönix-Klasse entwickelt, könnte es vielleicht funktionieren, aber im realen Leben ist das eine schlechte Idee.
[/Offtopic]

Anders sieht das aus, wenn das Clear von aussen aufgerufen wird, denn dann kann man auch von aussen stattdessen das Objekt freigeben und neu erstellen.

himitsu 5. Okt 2020 10:17

AW: Klassen: Clear -> Free -> Create?
 
Zitat:

Zitat von haentschman (Beitrag 1474857)
...nichts! :warn: Das das funktioniert ist eher Zufall :? Instanzen die in "Benutzung" sind, Pointer in Listen (die ihre Objekte selbst freigeben), sind sind nicht mehr gültig, weil der Pointer ein anderer und der vorhergehende freigeben ist. Dann dürfte es Zugriffsverletzungen hageln...:roll:

Noch schlimmer.
Im NextGen funktioniert es nichtmal, da du das Ojekt garnicht freigeben kannst, so lange noch andere Referenzen existieren,
und selbst wenn man es schafft, würde man dadurch eventuelle Weak-Referenzen schrotten. (auf nil setzen)

mkinzler 5. Okt 2020 10:38

AW: Klassen: Clear -> Free -> Create?
 
Zitat:

im nextgen
pgfnang

HeZa 5. Okt 2020 12:34

AW: Klassen: Clear -> Free -> Create?
 
Zitat:

Zitat von mkinzler (Beitrag 1474875)
Zitat:

im nextgen
pgfnang

Insider Witz?

mkinzler 5. Okt 2020 13:02

AW: Klassen: Clear -> Free -> Create?
 
next-gen ist tot
(previous-gen fomerly known as next-gen)

himitsu 5. Okt 2020 16:16

AW: Klassen: Clear -> Free -> Create?
 
dann halt MobileDingsabums ... das mit dem ARCZeugs


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