Einzelnen Beitrag anzeigen

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, 02: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