AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Warum virtuelle Destructoren?

Ein Thema von Muetze1 · begonnen am 18. Feb 2007 · letzter Beitrag vom 20. Feb 2007
Antwort Antwort
Seite 4 von 4   « Erste     234   
Benutzerbild von JasonDX
JasonDX
(CodeLib-Manager)

Registriert seit: 5. Aug 2004
Ort: München
1.062 Beiträge
 
#31

Re: unsichtbare Klassen

  Alt 20. Feb 2007, 01:33
So, jetzt nochmal gaaaaaanz laaaaangsam, und schoooooeeen detailliert:
Regeln:
  1. Wird eine Methode als Delphi-Referenz durchsuchenvirtual deklariert, erhaelt sie einen Eintrag in der VMT.
  2. Wird eine Methode als Delphi-Referenz durchsuchenoverride deklariert, wird der vorherige Eintrag der VMT ueberschrieben.
  3. Welche VMT verwendet wird, entscheidet das Instanzieren. Es wird immer auf die VMT verwiesen, dessen Konstruktor aufgerufen wurde.

So, und nun was passiert:
Gegeben sei folgende Klasse
Delphi-Quellcode:
TMeineKlasse = class(TObject)
  constructor Create();
  destructor Destroy(); //override;
end;
und diese 2 Variablen:
Delphi-Quellcode:
var
  meineKlasseObject: TObject;
  meineKlasse: TMeineKlasse;
welche beide mitTMeineKlasse.Create(); initialisiert werden.
Beobachten wir nun beide moeglichkeiten, und rufen bei beiden Instanzen die Destroy-Methode auf (weil du ja meinst, mit Free waere das ganze gezinkt )
Zuerst ohne override:
meineKlasse.Destroy(); Der Kompiler guckt: meineKlasse ist als TMeineKlasse deklariert. Davon soll nun die Methode "Destroy" aufgerufen werden. Ja, die is da deklariert, und dementsprechend wird auch TMeineKlasse.Destroy aufgerufen.
nunmeineKlasseObject.Destroy(); Der Kompiler guckt: meineKlasseObject ist als TObject deklariert. Davon soll nun die Methode "Destroy" aufgerufen werden. Ja, TObject.Destroy() gibts, und ist als virtual derklariert. Also guckt er in der VMT nach: Durch das instanzieren mit TMeineKlasse.Create() wird auf die VMT von TMeineKlasse verwiesen. Dort findet sich allerdings immernoch nur der Eintrag auf TObject.Destroy(), also wird TObject.Destroy aufgerufen. -> Speicherleck (siehe mein vorheriger Beitrag).

so, und nun das ganze mit override:
beim aufruf von meineKlasse.Destroy veraendert sich nichts. Der Kompiler sieht immernoch die Methode TMeineKlasse.Destroy() (weil meineKlasse als TMeineKlasse deklariert ist), und ruft dementsprechend auch TMeineKlasse.Destroy() auf.
Der Unterschied kommt beimeineKlasseObject.Destroy(); Hier guckt naemlich der Kompiler: Es soll die Methode Destroy von TObject aufgerufen werden. Diese Methode ist als virtual deklariert. Also gucken wir in der VMT nach. Weil diese aufgrund des Instanzierens durch TMeineKlasse.Create auf die VMT von TMeineKlasse geleitet wird, und der Eintrag von Destroy durch das override auf TMeineKlasse.Destroy() ueberschrieben wird, ruft der Kompiler auch TMeineKlasse.Destroy() auf -> Kein Speicherleck.

[Edit]Absatz entfernt. Er kam etwas persoenlich angreifender rueber als erhofft. Sorry, Klaerung per PN erfolgt.[/Edit]

greetz
Mike
Mike
Passion is no replacement for reason
  Mit Zitat antworten Zitat
Hansa

Registriert seit: 9. Jun 2002
Ort: Saarland
7.554 Beiträge
 
Delphi 8 Professional
 
#32

Re: unsichtbare Klassen

  Alt 20. Feb 2007, 01:50
Zitat von IngoD7:
...Ich habe keinen Bock, dir zu erklären, dass das Gras grün ist...
Ingo, keiner zwingt dich dazu. Ich jedenfalls nicht. Es gibt Leute die ähnlich argumentieren würden, auch wenn das Gras in Wirklichkeeit rot wäre.

Zitat von IngoD7:
und wenn du eigenen Klassen immer einen statischen Destruktor verpasst und diesen immer direkt mit xxx.Destroy aufrufst, dann wirst du möglicherweise immer zurecht kommen.
Von statisch war keine Rede, es geht um Vererbung. Speziell von leeren Klassen und dem Sinn davon, diese sogar zu überschreiben. Um mehr geht es nicht. Vielleicht kommt ja noch zu meinen beiden letzten Beispielen ein Kommentar.
Gruß
Hansa
  Mit Zitat antworten Zitat
Benutzerbild von JasonDX
JasonDX
(CodeLib-Manager)

Registriert seit: 5. Aug 2004
Ort: München
1.062 Beiträge
 
#33

Re: unsichtbare Klassen

  Alt 20. Feb 2007, 01:56
Zitat von Hansa:
Von statisch war keine Rede, es geht um Vererbung. Speziell von leeren Klassen und dem Sinn davon, diese sogar zu überschreiben. Um mehr geht es nicht. Vielleicht kommt ja noch zu meinen beiden letzten Beispielen ein Kommentar.
Verarschen kann ich mich selber. :
Zitat von Hansa:
Gut, dann schmeiße ich das eigene Destroy mal selber raus.
Wenns kein Destroy braeuchte, gaebs auch kein Problem. Der Destruktor wird eben gebraucht, und es soll auch der destruktor von TMeineKlasse aufgerufen werden, wenn die variable zwar mit TMeineKlasse.Create instanziert, aber als TObject deklariert wurde.
Akzeptiere das einfach. Wenn dus verstehen willst, lies dir den Thread nochmal durch. Wenn dus dann immernoch nicht verstanden hast, dann beachte den letzten Absatz meines vorherigen Beitrages.

greetz
Mike
Mike
Passion is no replacement for reason
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#34

Re: unsichtbare Klassen

  Alt 20. Feb 2007, 09:11
Könntet ihr bitte zurück zum Thema kommen (unsichtbare Klassen)?! Wenn ihr über Grundlagen der Objectorientierten Programmierung diskutieren wollt macht bitte einen eigenen Thread auf.
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
IngoD7

Registriert seit: 16. Feb 2004
464 Beiträge
 
Delphi 7 Enterprise
 
#35

Re: unsichtbare Klassen

  Alt 20. Feb 2007, 09:28
Zitat von SirThornberry:
Könntet ihr bitte zurück zum Thema kommen (unsichtbare Klassen)?! Wenn ihr über Grundlagen der Objectorientierten Programmierung diskutieren wollt macht bitte einen eigenen Thread auf.
Jetzt noch zum Thema zurück?

Kannst du den Thread aufteilen und diesen Teil mit Titel "Warum virtuelle Destructoren?" (oder so ähnlich) abhängen? Wäre vielleicht ganz nützlich, dieses Offtopic hier zu Ontopic woanders zu machen.
Danke.
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#36

Re: unsichtbare Klassen

  Alt 20. Feb 2007, 14:21
Zitat von IngoD7:
Zitat von SirThornberry:
Könntet ihr bitte zurück zum Thema kommen (unsichtbare Klassen)?! Wenn ihr über Grundlagen der Objectorientierten Programmierung diskutieren wollt macht bitte einen eigenen Thread auf.
Jetzt noch zum Thema zurück?

Kannst du den Thread aufteilen und diesen Teil mit Titel "Warum virtuelle Destructoren?" (oder so ähnlich) abhängen? Wäre vielleicht ganz nützlich, dieses Offtopic hier zu Ontopic woanders zu machen.
Danke.
so eben probiert und irgendwas ist dabei total schief gegangen Jetzt fehlt der erste Beitrag vom eigentlichen Beitrag obwohl mehrere abgespalten werden sollten.
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Elvis

Registriert seit: 25. Nov 2005
Ort: München
1.909 Beiträge
 
Delphi 2010 Professional
 
#37

Re: Warum virtuelle Destructoren?

  Alt 20. Feb 2007, 14:35
Öhm Jungs, ich glaube jeder von euch hat schon mindestens einmal in einem Thread mitgewirkt in dem versucht wurde dem großen H zu erklären was abstrakte Methoden sind, oder Interfaces, oder was-weiß-ich-nicht-alles.
Und ich glaube jeder von euch hat ab irgendeinem Punkt in diesen Threads aufgegeben. (Zwangsläufig, das große H weiß immer noch wofür abstrakte Methoden gut sind )

Warum gebt ihr nicht gleich von vornherein auf und antwortet einfach gar nicht mehr auf seine Fragen, die von seiner überheblicher Unwissenheit strotzen, dass sich mir die Eingeweide verknoten?
Man kann sich auch auf angenehmere Art Magengeschwüre zuziehen...
Robert Giesecke
I’m a great believer in “Occam’s Razor,” the principle which says:
“If you say something complicated, I’ll slit your throat.”
  Mit Zitat antworten Zitat
Cöster

Registriert seit: 6. Jun 2006
589 Beiträge
 
Turbo Delphi für Win32
 
#38

Re: Warum virtuelle Destructoren?

  Alt 20. Feb 2007, 16:03
Ich gebe noch nich auf, sondern fange jetzt erst an. Ich habe mich sehr über die Fortsetzung meines Threads unsichtbare Klassen amüsiert und möchte jetzt, wo er unter einem anderen Titel steht, auch meinen Senf dazu abgeben.

@Hansa:

Starte bitte eine Delphi-Anwendung mit folgendem Code:

Delphi-Quellcode:
unit Unit1;

interface

uses
   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
   StdCtrls;

type
   TForm1 = class(TForm)
      procedure FormCreate(Sender: TObject);
   private
      { Private-Deklarationen }
   public
      { Public-Deklarationen }
   end;

   TMeineKlasse = class
   public
      destructor Destroy;
   end;

var
   Form1: TForm1;

implementation

{$R *.DFM}

destructor TMeineKlasse.Destroy;
begin
   ShowMessage('Hey, Destruktor von TMeineKlasse wurde aufgerufen. ' +
      'Wenn diese Meldung gleich 2mal hintereinander kommt, ist es in der ' +
      'Tat absolut unnötig, Destruktoren mit override zu kennzeichnen.');
end;

procedure TForm1.FormCreate(Sender: TObject);
var
   MeineKlasse: TMeineKlasse;
   MeineKlasseObjekt: TObject;
begin
   MeineKlasse := TMeineKlasse.Create;
   MeineKlasse.Free;
   MeineKlasseObjekt := TMeineKlasse.Create;
   MeineKlasseObjekt.Destroy;
   ShowMessage('Wenn dies die erste oder zweite ausgegebene Meldung ' +
      'nach Programmstart ist, ist dies neben der unschönen Warnung, ' +
      'mit der mich der Compiler gerade die ganze Zeit nervt, ein weiterer ' +
      'Grund, Destruktoren zu overriden.');
end;

end.
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#39

Re: Warum virtuelle Destructoren?

  Alt 20. Feb 2007, 17:09
Ich gebe hier mal ein paar goldene Regeln vor.
An die Skeptiker hier: Ihr müsst das einfach als gegeben annehmen. Es wurde von Borland so designt.
Ich kann nur empfehlen, diese Regeln immer zu beachten. Ausdrucken, lesen und an den Monitor kleben...


1.) es gibt nur EINEN Destruktor! (Es kann nur einen geben)
Grund: ein Objekt kann auch ohne dass der Programmierer explizit der Destruktor aufgerufen hat, sterben.
Man denke hier nur an die Referenzzählung über COM Interfaces.
2.) der Destruktor muss immer Destroy heisen !
Pro Klasse darf man einen Destruktor namens Destroy deklarieren
3.) dagegen kann es beliebig viele Konstruktoren geben
4.) dieser eine Destruktor ist von Hause aus virtuell (und das hat seine Gründe und Vorteile, wie oben schon vor Einigen erklärt wurde)
Zusammen mit 1) bedeutet das, dass man keine neue Arten von Destruktoren einführen kann
5.) Innerhalb des Destruktors muss man grundsätzlich immer inherited als letzte Anweisung aufrufen.
Delphi-Quellcode:
destructor TMeinObjekt.destroy;
begin
   FInneresObj.Free;
   inherited; // <= wer das vergisst, den holt der Speicherfresser !!!
end;
Jede Klasse räumt seine selbst belegten Resourcen ab und muss dann den Destruktor der ererbten Klasse aufrufen. TObject.Destroy gibt dann der Speicher für das Objekt frei.
6.) Destroy wird grundsätzlich niemals direkt aufgerufen; es muss Free benutzt werden
Delphi-Quellcode:
FMeinObjekt.Destroy; // <= so ist der Ärger vorprogrammiert (FMeinObjekt könnte nil sein) !!
FMeinObjekt.Free; // das ist ok
FreeAndNil(FMeinObjekt); // auch erlaubt aber mehr Overhead

// möglich (aber ziemlich blöd, da es ja Free gibt) wäre auch
if Assigned(FMeinObjekt) then FMeinObjekt.Destroy;
7.) der Destruktor muss mit Override deklariert werden; alles andere wäre falsch (dies erklärt sich aus 1.) und 4.))
Delphi-Quellcode:
TMeinObjekt = class(TPersistent)
public
   destructor Destroy;override;
end;
Andreas
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 4 von 4   « Erste     234   


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:51 Uhr.
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