Delphi-PRAXiS
Seite 2 von 3     12 3      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Destruktor ueberschreiben - Warnung (https://www.delphipraxis.net/44374-destruktor-ueberschreiben-warnung.html)

alcaeus 18. Apr 2005 18:16

Re: Destruktor ueberschreiben - Warnung
 
Zitat:

Zitat von sakura
Default-Werte werden beim Kompilieren, wenn nicht vorhanden im Aufruf "gefakt". Da aber die ganzen Delphi-Funktionen auf TObject als Basis zugreifen, finden die dort keinen Default-Wert, so wird auch keiner durch den Compiler gefakt -> immer noch eine AV wenn diese auf Deine Implementierung treffen ;)

:roll: Also mach ich ein ueberladenes Free ohne Parameter, welches Intern das andere Free mit dem Parameter=False aufruft, das sollte dann hoffentlich mich und Delphi zufriedenstellen...

Greetz
alcaeus

shmia 18. Apr 2005 18:20

Re: Destruktor ueberschreiben - Warnung
 
Ein Destruktor darf grundsätzlich keine Parameter haben!!
(mit Ausnahme des versteckten Self-Parameters)
Dies gilt nicht nur für Delphi sondern auch für andere Programmiersprachen wie C++ u.s.w.
Bei Delphi ist der Destruktor von Anfang an virtuell und das ist auch gut so.

Wenn ein Objekt zerstört werden soll, gibt es nur 2 Informationen:
* das Objekt (bzw. der Zeiger auf das Objekt)
* es soll zerstört werden und alle verwendete Resourcen (insb. Speicher) freigegeben werden
Du diesem Zeitpunkt ist sehr häufig nicht einmal die genaue Klasse bekannt.
Vereinfacht ist die Aufrufereihenfolge so:
TObject.Free -> TEdit.Destroy -> TWinControl.Destroy -> TControl.Destroy -> TPersistent.Destroy -> TObject->Destroy

Die Methode Free ruft intern Destroy auf:
Delphi-Quellcode:
procedure TObject.Free;
asm
        TEST   EAX,EAX
        JE     @@exit
        MOV    ECX,[EAX]
        MOV    DL,1
        CALL   dword ptr [ECX].vmtDestroy
@@exit:
end;
// und jetzt mal übersetzt nach Pascal
procedure TObject.Free;
  if Assigned(self) then
     self.Destroy;
end;
Man sieht also, dass Destroy nur dann aufgerufen wird, wenn Self auf ein Objekt verweist.
Die Methode Free ist nicht virtuell und darf auch niemals verändert oder überschrieben werden !

weitere Info's:
http://www.dsdt.info/insider/sprache/destruktor.php

marabu 18. Apr 2005 18:28

Re: Destruktor ueberschreiben - Warnung
 
Zitat:

Zitat von Dax
Delphi-Referenz durchsuchenreintroduce sollte sein was du suchst.

borland
Use reintroduce when you want to hide an inherited virtual method with a new one.


Ich glaube nicht, dass das hier gewollt ist.

Die Sprachdefinition von Delphi (was Object Pascal) lässt ja mehrere Destruktoren zu, Borland rät aber davon ab, dieses feature zu benutzen. Sein Vorhandensein erhöht nicht die Mächtigkeit der Sprache. Alles, was ein Destruktor zu tun hat, weiss er - auch ohne Parameter. Über Parameter gesteuerte Aktionen im Destruktor gehören aus puristischer Sicht in eine andere Methode. Es gibt aber keine einheitliche Bestrafung für Verstösse.

Grüße vom marabu

@shmia: ein Destruktor darf Parameter haben - es muss nur bedacht werden, dass grundsätzlich die register calling convention gilt. Probier es aus - oder lese im Handbuch.

alcaeus 18. Apr 2005 18:31

Re: Destruktor ueberschreiben - Warnung
 
Problem geloest:

Delphi-Quellcode:
procedure Free; overload;
procedure Free(SaveFile: Boolean); overload;
//..
procedure TProgramOptions.Free;
begin
  Free(False);
end; //procedure TProgramOptions.Free;

procedure TProgramOptions.Free(SaveFile: Boolean);
begin
  if SaveFile then
  begin
    //...
  end; //if SaveFile then
  if Self <> nil then
    Destroy;
end; //procedure TProgramOptions.Free(SaveFile: Boolean);
Der Compiler motzt nicht, und sobald das Ganze testfaehig ist, werd ich sehn ob ich Besuch von einer huebschen AV bekomme ;)

Greetz
alcaeus

Robert_G 18. Apr 2005 18:37

Re: Destruktor ueberschreiben - Warnung
 
Was soll das denn werden?
Self <> nil ? :mrgreen: wie kann Self nil sein, wenn du doch auf Felder von der Instanz zugreifst bzw. in einer ihrer Methoden bist?

JasonDX 18. Apr 2005 18:39

Re: Destruktor ueberschreiben - Warnung
 
guck mal in TObject.Free ;)
Delphi-Quellcode:
procedure TObject.Free;
begin
  if Self <> nil then
    Destroy;
end;
self kann Nil sein. Self ist (IMHO) ein versteckter parameter, der die Adresse der Instanz übergibt
(bitte nich schlagen wenns falsch is :duck: )

sakura 18. Apr 2005 18:41

Re: Destruktor ueberschreiben - Warnung
 
Zitat:

Zitat von Robert_G
Was soll das denn werden?
Self <> nil ? :mrgreen: wie kann Self nil sein, wenn du doch auf Felder von der Instanz zugreifst bzw. in einer ihrer Methoden bist?

Das ist kein Problem:
Delphi-Quellcode:
var
  Button: TButton;
begin
  Button := nil;
  Button.Free;
end;
Was sonst, ausser NIL sollte für Self da übergeben werden ;-) Wird es auch, kannst Du gerne mal testen. Theoretisch kannst Du in jeder Methode Self auf nil überprüfen...

...:cat:...

shmia 18. Apr 2005 18:42

Re: Destruktor ueberschreiben - Warnung
 
Zitat:

Zitat von alcaeus
Problem geloest:

Delphi-Quellcode:
procedure Free; overload;
procedure Free(SaveFile: Boolean); overload;
//..

Das gefällt meinem Auge überhaupt nicht. :wink:
Richtig wäre doch, ein Property AutoSave:Boolean einzuführen und dann
Delphi-Quellcode:
procedure TProgramOptions.Destroy;
begin
   if FAutoSave then
      SaveToFile;
   ...
   inherited;
end;

sakura 18. Apr 2005 18:42

Re: Destruktor ueberschreiben - Warnung
 
Zitat:

Zitat von Chimaira
(bitte nich schlagen wenns falsch is :duck: )

Wenn es falsch ist, dann schon. Ist es aber nicht ;-)

...:cat:...

sakura 18. Apr 2005 18:43

Re: Destruktor ueberschreiben - Warnung
 
Zitat:

Zitat von shmia
Das gefällt meinem Auge überhaupt nicht. :wink:

Meinen auch nocht :cyclops:

Zitat:

Zitat von shmia
Richtig wäre doch, ein Property AutoSave:Boolean einzuführen und dann

Das wäre der korrekt OOP-Weg :thumb:

...:cat:...


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:56 Uhr.
Seite 2 von 3     12 3      

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 by Thomas Breitkreuz