Delphi-PRAXiS

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 17:49


Destruktor ueberschreiben - Warnung
 
Hallo allerseits,

ich versuche in einer von TObject abgeleiteten Klasse den Destruktor zu ueberschreiben, um einen Parameter hinzuzufuegen (fragt nicht warum, ich will es so, weil es komfortabel waere ;))

Delphi-Quellcode:
  TProgramOptions = class(TObject)
    private
      //...
    public
      constructor Create(LoadFile: Boolean=False);
      procedure Free(SaveFile: Boolean=False); overload;
      destructor Destroy(SaveFile: Boolean=False); overload;
      //...
  end; //type TProgramOptions = class(TObject)
Nun schimpft der Compiler aber rum, dass mein Destroy die Methode der Basisklasse ueberschreibt ("Method 'Destroy' hides virtual method of base type 'TObject'). Ich weiss es ist nur eine Warnung, aber mich interessiert, wie ich das umgehen kann. Welches Schluesselwort muss ich anstatt overload verwenden?

Greetz
alcaeus

Binärbaum 18. Apr 2005 17:51

Re: Destruktor ueberschreiben - Warnung
 
Gab es da nicht sowas wie
Delphi-Quellcode:
override;
:?:

MfG
Binärbaum

alcaeus 18. Apr 2005 17:51

Re: Destruktor ueberschreiben - Warnung
 
Zitat:

Zitat von Binärbaum
Gab es da nicht sowas wie
Delphi-Quellcode:
override;
:?:

Ja, das gibt es. Allerdings muessen fuer override die Parameterliste und der Rueckgabetyp uebereinstimmen ;)

Greetz
alcaeus

sakura 18. Apr 2005 17:53

Re: Destruktor ueberschreiben - Warnung
 
:warn:
Man sollte (darf) für den Destructor die Parameterliste nicht ändern. Das führt nur zu unnötigen AVs!
:warn:

...:cat:...

Dax 18. Apr 2005 17:53

Re: Destruktor ueberschreiben - Warnung
 
Delphi-Referenz durchsuchenreintroduce sollte sein was du suchst.

Die Muhkuh 18. Apr 2005 17:54

Re: Destruktor ueberschreiben - Warnung
 
Zitat:

Zitat von sakura
:warn:
Man sollte (darf) für den Destructor die Parameterliste nicht ändern. Das führt nur zu unnötigen AVs!
:warn:

...:cat:...

Man könnte doch noch eine Public-Variable definieren und wenn die auf true steht, wird halt noch gespeichert^^

alcaeus 18. Apr 2005 17:54

Re: Destruktor ueberschreiben - Warnung
 
Zitat:

Zitat von sakura
:warn:
Man sollte (darf) für den Destructor die Parameterliste nicht ändern. Das führt nur zu unnötigen AVs!
:warn:

Na gut, also gibts nur ein Free mit Parameter, und das wars auch schon. Danke trotzdem..
Allerdings wuerde mich jetzt interessieren warum es die AVs gibt ;)

Greetz
alcaeus

sakura 18. Apr 2005 18:01

Re: Destruktor ueberschreiben - Warnung
 
Zitat:

Zitat von alcaeus
Na gut, also gibts nur ein Free mit Parameter, und das wars auch schon. Danke trotzdem..

Auch nicht entscheidend besser, da Free intern durch Delphi gerne genutzt wird, um Objekte freizugeben.

Zitat:

Zitat von alcaeus
Allerdings wuerde mich jetzt interessieren warum es die AVs gibt ;)

Und Free ruft Destroy auf...

...:cat:...

alcaeus 18. Apr 2005 18:03

Re: Destruktor ueberschreiben - Warnung
 
Zitat:

Zitat von sakura
Auch nicht entscheidend besser, da Free intern durch Delphi gerne genutzt wird, um Objekte freizugeben.

Sollte nicht zu sehr ins Gewicht fallen, der Parameter ist mit einem Default-Wert belegt. Evtl. wird die Collection vor dem freigeben eben nicht gespeichert, aber was solls...

Greetz
alcaeus

sakura 18. Apr 2005 18:13

Re: Destruktor ueberschreiben - Warnung
 
Zitat:

Zitat von alcaeus
Sollte nicht zu sehr ins Gewicht fallen, der Parameter ist mit einem Default-Wert belegt. Evtl. wird die Collection vor dem freigeben eben nicht gespeichert, aber was solls...

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 ;)

...:cat:...

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:...

Muetze1 18. Apr 2005 18:43

Re: Destruktor ueberschreiben - Warnung
 
--- selbsterlediger, da verpennt ---

alcaeus 18. Apr 2005 18:46

Re: Destruktor ueberschreiben - Warnung
 
http://dpchat.dpexperte.de/smileys/icon_mecker.gif Ich koennte ja oben auch noch eine Abfrage auf nil hinzufuegen, aber dann werdet ihr trotzdem noch wegen der OOP-Property rumschreien. Also fliegt das ueberladene Free raus und ich fueg die Property ein. :roll:

Greetz
alcaeus

Robert_G 18. Apr 2005 19:03

Re: Destruktor ueberschreiben - Warnung
 
Zitat:

Zitat von sakura
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:...

Er kann Free aufrufen ohne dir eine read AV an 0x0 zu geben? :gruebel: Müsste man testen, aber ich kann's mir kaum vorstellen...

Sorry, aber ich überschreibe nur Destruktoren, mir ist bisher noch nie sowas perverses, wie das hier besprochene, eingefallen. :oops:

alcaeus 18. Apr 2005 19:24

Re: Destruktor ueberschreiben - Warnung
 
Zitat:

Zitat von Robert_G
Sorry, aber ich überschreibe nur Destruktoren, mir ist bisher noch nie sowas perverses, wie das hier besprochene, eingefallen. :oops:

Danke. Wenn ich dich nicht kennen wuerde, waere ich jetzt eingeschnappt ;)
Ich hab aber die Property implementiert, ist ja egal wie ich es mache solange es funktioniert ;)

Greetz
alcaeus


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:52 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 by Thomas Breitkreuz