Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Wo wird der Heap von Feldvariablen von Objekten freigegeben? (https://www.delphipraxis.net/212532-wo-wird-der-heap-von-feldvariablen-von-objekten-freigegeben.html)

QuickAndDirty 23. Feb 2023 12:48

Wo wird der Heap von Feldvariablen von Objekten freigegeben?
 
TObject.Destroy ist ja nun mal ohne code
TObject.Free auch (wenn man nicht im ARC modus ist)
Also brauche ich Inherited Destroy in Nachfahren auch nicht aufrufen, oder?
Delphi-Quellcode:
unit test
interface
uses System.types, classes, math, TypInfo, sysutils;
type
  TMYObject = class
  public
    owner:tobject;
    Number:Integer;
    Destructor Destroy;override;
  end;
var MYObject:tMyObject;
implementation
Destructor TMYObject.destroy;
Begin
end;

initialize
  MYObject := tMyObject.create;
  MYObject.Owner := MyObject;
  MYObject.Number := 20000;
  MYObject.free;
end.
Wie weiß Delphi (oder der Speichermanager) dass Owner und Number auf dem Heap frei sind wenn MYObject.free keinen Code ausführt?

Uwe Raabe 23. Feb 2023 13:08

AW: Wo wird der Heap von Feldvariablen von Objekten freigegeben?
 
Zitat:

Zitat von QuickAndDirty (Beitrag 1519020)
Also brauche ich Inherited Destroy in Nachfahren auch nicht aufrufen, oder?

Doch, musst du! Embarcadero wartet bloß darauf, das das jemand so macht, um bei der nächsten Version irgendeinen immens wichtigen Code dort auszuführen, der dein Programm dann crashen lässt, weil er dort nicht ausgeführt wird.

OK, Spaß beiseite. Man ruft immer (irgendjemand findet hier sicher noch eine Ausnahme) inherited Destroy auf ebenso wie inherited Create, weil man eben nicht von obigem Szenario betroffen sein möchte, falls es mal wirklich so kommt.

Zitat:

Zitat von QuickAndDirty (Beitrag 1519020)
Wie weiß Delphi das Owner und Number auf dem Heap frei sind wenn MYObject.free keinen Code ausführt?

Create und Destroy sind nur die Stellen, wo der Delphi-Entwickler eingreifen soll/kann, z.B. wenn Felder in der Klasse auf Instanzen zeigen, die ebenfalls freigegeben werden müssen. Die eigentliche Erzeugung und Freigabe der Instanzen und deren Inhalte erfolgt in NewInstance und FreeInstance, die vom Compiler implizit aufgerufen werden (z.B. _ClassCreate und _ClassDestroy, aber das ist ein ziemlich komplexes Thema und nicht in zwei Sätzen umfassend zu beschreiben). Das unterscheidet einen constructor/destructor eben von einer normalen (class-)method eines TObjects.

himitsu 23. Feb 2023 14:17

AW: Wo wird der Heap von Feldvariablen von Objekten freigegeben?
 
Andersrum: Man kann auch einfach immer und überall inherited reinmachen, selbst wenn es noch nicht überschrieben ist.

QuickAndDirty 23. Feb 2023 14:26

AW: Wo wird der Heap von Feldvariablen von Objekten freigegeben?
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1519021)
Zitat:

Zitat von QuickAndDirty (Beitrag 1519020)
Also brauche ich Inherited Destroy in Nachfahren auch nicht aufrufen, oder?

Doch, musst du! Embarcadero wartet bloß darauf, das das jemand so macht, um bei der nächsten Version irgendeinen immens wichtigen Code dort auszuführen, der dein Programm dann crashen lässt, weil er dort nicht ausgeführt wird.

OK, Spaß beiseite. Man ruft immer (irgendjemand findet hier sicher noch eine Ausnahme) inherited Destroy auf ebenso wie inherited Create, weil man eben nicht von obigem Szenario betroffen sein möchte, falls es mal wirklich so kommt.

Zitat:

Zitat von QuickAndDirty (Beitrag 1519020)
Wie weiß Delphi das Owner und Number auf dem Heap frei sind wenn MYObject.free keinen Code ausführt?

Create und Destroy sind nur die Stellen, wo der Delphi-Entwickler eingreifen soll/kann, z.B. wenn Felder in der Klasse auf Instanzen zeigen, die ebenfalls freigegeben werden müssen. Die eigentliche Erzeugung und Freigabe der Instanzen und deren Inhalte erfolgt in NewInstance und FreeInstance, die vom Compiler implizit aufgerufen werden (z.B. _ClassCreate und _ClassDestroy, aber das ist ein ziemlich komplexes Thema und nicht in zwei Sätzen umfassend zu beschreiben). Das unterscheidet einen constructor/destructor eben von einer normalen (class-)method eines TObjects.

Also wann wird _ClassDestroy aufgerufen? Es ist ne CompilerMagic sache nehme ich an so wie der RefCount bei ARC.
Wird es automatisch nach .Free eingefügt?

QuickAndDirty 23. Feb 2023 14:30

AW: Wo wird der Heap von Feldvariablen von Objekten freigegeben?
 
Zitat:

Zitat von himitsu (Beitrag 1519023)
Andersrum: Man kann auch einfach immer und überall inherited reinmachen, selbst wenn es noch nicht überschrieben ist.

aber warum? Meinst du jetzt nur destructor und constructor oder wirklich "überall" ?

himitsu 23. Feb 2023 15:09

AW: Wo wird der Heap von Feldvariablen von Objekten freigegeben?
 
überall

Uwe Raabe 23. Feb 2023 15:13

AW: Wo wird der Heap von Feldvariablen von Objekten freigegeben?
 
Zitat:

Zitat von QuickAndDirty (Beitrag 1519029)
aber warum?

Ich dachte, das hätte ich deutlich gemacht.

Zitat:

Zitat von QuickAndDirty (Beitrag 1519027)
Also wann wird _ClassDestroy aufgerufen? Es ist ne CompilerMagic sache nehme ich an so wie der RefCount bei ARC.
Wird es automatisch nach .Free eingefügt?

Genauer gesagt nach dem Destroy, weil das ein destructor ist. Das Free ist ja nur eine ganz normale Methode. Vor dem Destroy wird übrigens auch noch _BeforeDestruction aufgerufen. Diese Aufrufe sieht man nirgendwo im Quellcode, sondern der Compiler setzt sie automagisch ein.

Zitat:

Zitat von himitsu (Beitrag 1519030)
überall

Nein, nicht überall - zumindest nicht bedingungslos. So sollte man bei einem override von Assign nur dann das inherited aufrufen, wenn man weiß, dass die Parentklasse da noch was Sinnvolles macht. Leitet man direkt von TPersistent ab oder gibt es in der Hierarchie dazwischen kein Assign-override, dann sollte man inherited nur dann aufrufen, wenn man mit der Source nichts anfangen kann. Sinngemäß gilt das auch für AssignTo.

himitsu 23. Feb 2023 15:28

AW: Wo wird der Heap von Feldvariablen von Objekten freigegeben?
 
Nja, gundsätzlich erstmal überall, außer explizit dort, es man wirklich den Vorfahren nicht ausführen will.

Letzteres macht man bewusst.
Und so kann man es aber auch nicht vergessen, wenn man es (erstmal) standardmäßig immer macht.

Bei vererbten Forms, macht der Formdesigner auch erstmal in alle von ihm erzeugte Events rein.


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:34 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz