Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Wann .Free und wann .Destoy benutzen (https://www.delphipraxis.net/95609-wann-free-und-wann-destoy-benutzen.html)

DelphiManiac 10. Jul 2007 12:12


Wann .Free und wann .Destoy benutzen
 
Hallo,
habe eine Frage zur Benutzung des Destuktors meiner Klasse.

ich kann ja folgendes schreiben:

Delphi-Quellcode:
meinObjekt.Free;
oder ich rufe den von mir erstellten Destructor

Delphi-Quellcode:
meinObjekt.Destroy;
auf...

Gut meine Frage nun, was macht .Free?
Setzt free nur die Objektreferenz auf NULL?
Oder ruft Free auf den Destruktor auf?

Danke schonmal

scrat1979 10. Jul 2007 12:14

Re: Wann .Free und wann .Destoy benutzen
 
Hallo!

hier findest Du des Rätsels Lösung :-)

SCRaT

mkinzler 10. Jul 2007 12:14

Re: Wann .Free und wann .Destoy benutzen
 
Nimm .Free. Hier werden verschiedene Test durchgeführt und dann .Destroy aufgerufen. man sollte .Destroy nie manuell aufrufen.

DelphiManiac 10. Jul 2007 12:25

Re: Wann .Free und wann .Destoy benutzen
 
Danke,
war genau das was ich gesucht habe!!

Weiß jetzt auch wo mein Fehler war,.. habe in meine Klasse den Destruktor nicht überschrieben,
demzufolge wurde er auch nie aufgerufen...


Danke!

dajuhsa 10. Jul 2007 12:44

Re: Wann .Free und wann .Destoy benutzen
 
also ist
Delphi-Quellcode:
XYZ.Free
das gleiche wie
Delphi-Quellcode:
if XYZ <> nil then XYZ.Destroy
?

sakura 10. Jul 2007 12:47

Re: Wann .Free und wann .Destoy benutzen
 
Zitat:

Zitat von dajuhsa
also ist
Delphi-Quellcode:
XYZ.Free
das gleiche wie
Delphi-Quellcode:
if XYZ <> nil then XYZ.Destroy
?

Momentan ja, aber das kann sich theoretisch in kommenden Delphi-Versionen ändern oder in Delphi.NET anders implementiert sein :zwinker: Aber nach außen bleibt einfach immer der AUfruf zu .Free :)

...:cat:...

mkinzler 10. Jul 2007 12:50

Re: Wann .Free und wann .Destoy benutzen
 
Ja :

Zitat:

Zitat von System.pas
procedure TObject.Free;
begin
if Self <> nil then
Destroy;
end;


sirius 10. Jul 2007 19:21

Re: Wann .Free und wann .Destoy benutzen
 
Zitat:

Zitat von sakura
Momentan ja, aber das kann sich theoretisch in kommenden Delphi-Versionen ändern oder in Delphi.NET anders implementiert sein :zwinker: Aber nach außen bleibt einfach immer der AUfruf zu .Free :)

Wäre doch mal ein Ding, wenn die Free-Methode demnächst autmatisch den Zeiger auf nil setzt :mrgreen:

mkinzler 10. Jul 2007 19:24

Re: Wann .Free und wann .Destoy benutzen
 
Zitat:

Wäre doch mal ein Ding, wenn die Free-Methode demnächst autmatisch den Zeiger auf nil setzt
Wird wohl nicht gehen. dafür gibt es ja aber FreeAndNil()

SirThornberry 10. Jul 2007 19:46

Re: Wann .Free und wann .Destoy benutzen
 
Zitat:

Zitat von mkinzler
Zitat:

Wäre doch mal ein Ding, wenn die Free-Methode demnächst autmatisch den Zeiger auf nil setzt
Wird wohl nicht gehen. dafür gibt es ja aber FreeAndNil()

ich würde es nicht pauschalisieren. Mit Compilermagic geht einiges. Siehe Strings und deren Handling.

sirius 10. Jul 2007 20:41

Re: Wann .Free und wann .Destoy benutzen
 
Zitat:

Zitat von mkinzler
Zitat:

Wäre doch mal ein Ding, wenn die Free-Methode demnächst autmatisch den Zeiger auf nil setzt
Wird wohl nicht gehen. dafür gibt es ja aber FreeAndNil()

Wir wollen hier objektorientiert programmieren und müssen dann auf so eine stupide Prozedur zurückgreifen.
Der Compiler muss halt einfach einmal mehr mitdenken und beim Aufruf von free die self-varaible als Referenz übergeben.

xaromz 10. Jul 2007 20:47

Re: Wann .Free und wann .Destoy benutzen
 
Hallo,

Zitat:

Zitat von sirius
Wäre doch mal ein Ding, wenn die Free-Methode demnächst autmatisch den Zeiger auf nil setzt :mrgreen:

viel zu kurz gedacht:
Delphi-Quellcode:
var
  A, B: TObject;
begin
  A := TObject.Create;
  B := A;
  A.Free;
end;
Angenommen, Free setzt A auf nil, welchen Wert hat dann B?

Gruß
xaromz

mkinzler 10. Jul 2007 20:48

Re: Wann .Free und wann .Destoy benutzen
 
Er müsste erkennen, daß eine Variable außerhalb des Scopes der Klasse die gerade freigegebene Instanz referenziert und diese dann auf Nil setzen.

xaromz 10. Jul 2007 20:52

Re: Wann .Free und wann .Destoy benutzen
 
Hallo,
Zitat:

Zitat von mkinzler
Er müsste erkennen, daß eine Variable außerhalb des Scopes der Klasse die gerade freigegebene Instanz referenziert und diese dann auf Nil setzen.

Überprüfung aller Variablen auf mögliche Verweise? Jetzt weiß ich, wozu wir Quad-Prozessoren brauchen :mrgreen: .

Gruß
xaromz

mkinzler 10. Jul 2007 21:11

Re: Wann .Free und wann .Destoy benutzen
 
Zitat:

Überprüfung aller Variablen auf mögliche Verweise?
Nein er könnte ja schon den Zusammenhang von der Methode und dem Objekt auf dem es angewandt wurde. Meine Frage war als Antwort auf Sirius' Antwort gedacht und sollte zeigen, daß es nicht so einfach ist.

sirius 10. Jul 2007 21:23

Re: Wann .Free und wann .Destoy benutzen
 
@xaromz: Das ist ja ne alberne Annahme. Was kann denn der Compiler dafür wenn ich mir irgendwo den Pointer auf ein Objekt noch ein zweites oder drittes Mal merke. auch freeandnil setzt bei dir B nicht auf nil. So kann ich (wenn auch etwas umständlicher wegen den Referenzzählern) auch strings etc."austrixen".
Dafür gibts eben Referenzzähler, und zack sind wir bei Interfaces angelangt.

@mkinzler
Delphi-Quellcode:
procedure Tobject.free(var self:Tobject);
begin
  if self<>nil then destroy
  self:=nil;
end;
Das ist Aufgabe des Compilers, da mal eine Referenz zu geben.

mkinzler 10. Jul 2007 21:27

Re: Wann .Free und wann .Destoy benutzen
 
Nur das das setzen von self auf nil unnötig ist, da nach dem Ende der Methode self nicht mehr existiert. Aber die variable, die das Objekt referenziert hat immer noch den Wert.

Hawkeye219 10. Jul 2007 21:29

Re: Wann .Free und wann .Destoy benutzen
 
Hallo,

Zitat:

Zitat von SirThornberry
Mit Compilermagic geht einiges.

Zitat:

Zitat von sirius
Der Compiler muss halt einfach einmal mehr mitdenken und beim Aufruf von free die self-varaible als Referenz übergeben.

wie würdet ihr das - als Compilerbauer - im folgenden Fall lösen?

Delphi-Quellcode:
TDemoClass = class
private
  ...
public
  property Control: TWhateverClass
    read GetControl write SetControl;
end;

var
  Instance : TDemoClass;
begin
  ...
  Instance.Control.Free;
  ...
end;
Das Beispiel wirkt konstruiert, aber ähnliche Codestücke findet man in der VCL.

Ein automatisch generiertes "Instance.Control := nil" nach dem Aufruf der Free-Methode funktioniert nur, wenn der Setter dies geeignet verarbeitet. Welchen Code soll der Compiler erzeugen, wenn kein Setter vorhanden ist?

Die Prozedur FreeAndNil ist ein einfaches Werkzeug, mit dessen Hilfe der Programmierer eine Instanz freigeben und eine zugehörige Referenz sicher löschen kann. Nur der Programmierer kann wissen, wann und wo das geschehen sollte, und ob eventuell weitere Referenzen existieren, die ebenfalls gelöscht werden müssen.

Gruß Hawkeye

xaromz 10. Jul 2007 21:36

Re: Wann .Free und wann .Destoy benutzen
 
Hallo,
Zitat:

Zitat von sirius
@xaromz: Das ist ja ne alberne Annahme. Was kann denn der Compiler dafür wenn ich mir irgendwo den Pointer auf ein Objekt noch ein zweites oder drittes Mal merke. auch freeandnil setzt bei dir B nicht auf nil.

die Annahme ist nicht albern. Es geht hier um die Konsistenz. Mit FreeAndNil setze ich explizit eine Variable. Free tut das nicht. Wäre dem so, hätten wir ein ziemlich komisches Konstrukt: Eine Methode wirkt sich auf die Variable aus, über die sie aufgerufen wurde, aber auf keine andere. In einer solchen Sprache möchte ich nicht programmieren.

Gruß
xaromz

sirius 11. Jul 2007 08:19

Re: Wann .Free und wann .Destoy benutzen
 
Zitat:

Zitat von xaromz
Hallo,
die Annahme ist nicht albern. Es geht hier um die Konsistenz. Mit FreeAndNil setze ich explizit eine Variable. Free tut das nicht. Wäre dem so, hätten wir ein ziemlich komisches Konstrukt: Eine Methode wirkt sich auf die Variable aus, über die sie aufgerufen wurde, aber auf keine andere. In einer solchen Sprache möchte ich nicht programmieren.
Gruß
xaromz

Programmierst du aber :mrgreen:
Delphi-Quellcode:
var s:string;
begin
  //jetzt ist s nil
  s:='Hallo Welt';
  //und jetzt zeigt s ganz woanders hin
  //ähnliches für dynamische Arrays
end;
@Hawkeye
Na du übergibst bei free "einfach" noch den zweiten Parameter mit, der auf nil gesetzt werden soll. Bei create wird ja auch noch vom Compiler die TypeInfo mitgeliefert. Es gibt noch weitere Funktionen (freemem/dispose), wo der Compiler einfach noch 1 Parameter mit anhängt. Und wenn du mit mehreren Referenzen auf ein Objekt arbeitest, dann nimm doch lieber ein Interface.

Generell besteht bei sowas natürlich immer die Frage der Sinnfälligkeit. Aber wann brauch man denn nochmal einen Zeiger auf ein Objekt, dass nicht mehr existiert? Und wieviele Probleme diesbezüglich tauchten schon in der DP auf ("assigned funktoiniert nicht!" --> "Du musst den Zeiger auf nil setzen")?

xaromz 11. Jul 2007 08:39

Re: Wann .Free und wann .Destoy benutzen
 
Hallo,
Zitat:

Zitat von sirius
Zitat:

Zitat von xaromz
In einer solchen Sprache möchte ich nicht programmieren.

Programmierst du aber :mrgreen:
Delphi-Quellcode:
var s:string;
begin
  //jetzt ist s nil
  s:='Hallo Welt';
  //und jetzt zeigt s ganz woanders hin
  //ähnliches für dynamische Arrays
end;

nein, tu ich nicht. Wo ist in Deinem Beispiel eine Methode? Was hat eine Zuweisung mit dam Ganzen zu tun?

Zitat:

Zitat von sirius
Generell besteht bei sowas natürlich immer die Frage der Sinnfälligkeit.

Da hast Du Recht.
Zitat:

Zitat von sirius
Aber wann brauch man denn nochmal einen Zeiger auf ein Objekt, dass nicht mehr existiert? Und wieviele Probleme diesbezüglich tauchten schon in der DP auf ("assigned funktoiniert nicht!" --> "Du musst den Zeiger auf nil setzen")?

Natürlich braucht man den Zeiger danach nicht mehr, aber der vorgeschlagene Weg ist nicht geeignet, das Problem zu lösen.

Gruß
xaromz

Hawkeye219 11. Jul 2007 08:57

Re: Wann .Free und wann .Destoy benutzen
 
Hallo sirius,

ich bestreite nicht, daß ein wenig compiler magic in diesem Fall nützlich wäre. Ich wollte - genau wie xaromz - nur aufzeigen, daß es nicht in allen Fällen möglich sein wird, die notwendigen Befehle zum Löschen der Referenz(en) automatisch erzeugen zu lassen. Dies scheitert meiner Meinung nach spätestens dann, wenn die Referenz ein Funktionsergebnis ist. Ob es sinnvoll ist, so etwas zu programmieren, sei dahingestellt. Es kommt vor, deshalb muß ein Compiler auch diese Fälle berücksichtigen. Kann er diese Aufgabe aber nicht vollständig übernehmen, so daß ich als Programmierer gezwungen bin, in "schwierigen" Situation selbst tätig zu werden, dann trifft xaromz' Aussage auch für mich zu: In einer solchen Sprache möchte ich nicht programmieren.

Zitat:

Und wenn du mit mehreren Referenzen auf ein Objekt arbeitest, dann nimm doch lieber ein Interface.
Genau das mache ich (nicht nur in diesem Fall) auch. Die wenigen Probleme (z.B. cyclic references) lassen sich relativ leicht lösen, auf der anderen Seite stehen eine (fast) automatische Speicherverwaltung und -freigabe sowie bessere Möglichkeiten, ein großes Programm zu modularisieren.

Gruß Hawkeye


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