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 3 von 4     123 4      
Muetze1
(Gast)

n/a Beiträge
 
#21

Re: unsichtbare Klassen

  Alt 19. Feb 2007, 09:12
gleiches gilt neben dem Aufruf von xxx.Free; auch für die Verwendung/Aufruf von FreeAndNil(xxx);
  Mit Zitat antworten Zitat
Hansa

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

Re: unsichtbare Klassen

  Alt 19. Feb 2007, 18:42
Vorab : der Thread hier wurde vom Fragesteller woanders mittlerweile als OT gebrandmarkt.

Nichtsdestotrotz : das ganze sieht doch so aus :

Delphi-Quellcode:
destructor TObject.Destroy;
begin
end;
Wie Muetze richtig aus der Hilfe zitiert hat, ist es dasselbe einfach "class" zu schreiben oder eben "class (TObject)". Also ist das ein Nachfahre von TObject. Aber nur pro forma. Warum soll jetzt da nochmals ein leerer Destructor per override auch noch überschrieben werden ? Vermute sogar, dass der Delphi-Linker das automatisch entfernt. Naheliegend wäre auch, das die vereinfachte Schreibweise Class erlaubt wird, damit keiner auf die Idee kommt, so was überflüssigerweise zu machen.
Gruß
Hansa
  Mit Zitat antworten Zitat
Benutzerbild von JasonDX
JasonDX
(CodeLib-Manager)

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

Re: unsichtbare Klassen

  Alt 19. Feb 2007, 19:09
Zitat von Hansa:
Also ist das ein Nachfahre von TObject. [...] Warum soll jetzt da nochmals ein leerer Destructor per override auch noch überschrieben werden ?
Hmm, ein paar OOP-Tutorials wuerden dir nicht schlecht tun:
Du hast eine beliebige Klasse, bspw. TMeineKlasse. Im Konstruktor dieser Klasse wird bspw. Speicher allociert, oder irgendetwas instanziert, das im Destruktor wieder freigegeben werden muss.
Nun gibts 2 Moeglichkeiten:
Delphi-Quellcode:
//1.
destructor Destroy();
//2.
destructor Destroy(); override;
Du behauptest, zweiteres mache keinen Sinn. Analysieren wir mal, was die unterschiede sind:
Wenn eine Variable als TMeineKlasse deklariert ist, macht es keinen Unterschied.
Wenn aber eine Variable nicht als TMeineKlasse, sondern als Vorfahre (bspw. TObject) deklariert ist, aber als TMeineKlasse instanziert wurde, muss auch der Destruktor von TMeineKlasse aufgerufen werden.
Passiert das aber? Nein.
Delphi-Quellcode:
TMeineKlasse = class
  constructor Create();
  destructor Destroy();
  speicher: Pointer;
end;
//...
constructor TMeineKlasse.Create();
begin
  speicher = allocmem(100);
end;

destructor TMeineKlasse.Create();
begin
  freemem(speicher);
end;



procedure ProbiersAus();
var
  x: TObject;
begin
  x := TMeineKlasse.Create();
  x.Free(); //Es wird TObject.Free aufgerufen!
end;
Gibt ein schoenes Speicherleck. mit dem ueberschreiben des Destruktors passiert das nicht.

greetz
Mike
Mike
Passion is no replacement for reason
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#24

Re: unsichtbare Klassen

  Alt 19. Feb 2007, 19:10
Zitat von Hansa:
Warum soll jetzt da nochmals ein leerer Destructor per override auch noch überschrieben werden ?
Weil sonst sein FObject.Free bzw. das Clear nicht aufgerufen wird in seinem Constructor. Das Override ist notwendig, sonst wird der Destructor in der Ableitung nicht aufgerufen (siehe vorherige Ausführungen). Der Destructor in TObject ist leer, ok, aber dann könntest du vllt. propagandieren, dass der Inherited Aufruf weggelassen werden könnte - das stimmt, aber das Override ist notwendig für den Aufruf.

Den Aufruf von Inherited würde ich aber auch nicht weglassen, da sonst bei einer Änderung des Inhalts des Destructors in TObject seitens Borlands nicht Rechnung getragen würde.

/EDIT: roter Rahmen verzweifelt gesucht...
  Mit Zitat antworten Zitat
IngoD7

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

Re: unsichtbare Klassen

  Alt 19. Feb 2007, 20:13
Zitat von Hansa:
Warum soll jetzt da nochmals ein leerer Destructor per override auch noch überschrieben werden ?
Deshalb:

Zitat von IngoD7:
Zitat von Muetze1:
/EDIT: Wenn du das Override nicht angibst, dann erhälst du zum einen einen Hinweis/Warnung vom Compiler und zum anderen wird dein Destructor nie ausgeführt.
Das bedarf aber noch ein paar Erklärungen.

Er wird [...] nicht ausgeführt, wenn zum Freigeben von TMeinObjekt ein MeinObjekt.Free benutzt wird. Free ist von TObject geerbt und ruft eben nur den Destruktor destroy von TObject auf, wenn dessen Virtualität nicht Rechnung getragen wird in den abgeleiteten Klassen. Durch ein override würde MeinObjekt.Free den Destructor destroy von TMeinObjekt aufrufen. Daher sollten Destruktoren in der Regel immer ihren Ahnen per override überschreiben. Eben weil sonst ein Free den eigenen Destruktor nicht "erreichen" würde, sondern in TObject "hängenbleiben" würde.
[...]
Probiere es aus.
  Mit Zitat antworten Zitat
IngoD7

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

Re: unsichtbare Klassen

  Alt 19. Feb 2007, 20:26
@JasonDX

Zitat von JasonDX:
Wenn eine Variable als TMeineKlasse deklariert ist, macht es keinen Unterschied.
Doch. Bei Benutzung von Free macht es immer einen Unterschied. Es gibt in der Regel nur das eine, geerbte Free in TObject. Das wird auch angesprungen wenn ein TMeineKlasse.Free aufgerufen wird. Und dieses angesprungenen TObject.Free würde jetzt nur den eigenen Destructor (in TObject) aufrufen, wenn der Destructor der abgeleiteten Klasse TMeineKlasse kein override besitzt. Und das eben auch bei
Delphi-Quellcode:
var
  x: TMeineKlasse;
Dieser "Umweg" über das Free, welches nur im Urahnen TObject existiert, macht beim Aufruf des Destructors den kleinen Unterschied.
  Mit Zitat antworten Zitat
Hansa

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

Re: unsichtbare Klassen

  Alt 19. Feb 2007, 20:34
Ich liebe Grundsatzdiskussionen, aber wir sind anscheinend noch lange nicht fertig.

Erkläre mir mal bitte einer, was ich in diesem Fall mit dem overrride soll :
Delphi-Quellcode:
Unit Unit2;

interface

implementation

uses
  Dialogs,
  SysUtils;

type

TMeineKlasse = class
  private
    i : integer;
  protected
    constructor Create;
    destructor Destroy;
end;

var MeineKlasse : TMeineKlasse;

constructor TMeineKlasse.Create;
begin
  i := 123;
end;

destructor TMeineKlasse.Destroy;
begin
showmessage ('Destroy '+IntToStr (i));
end;

begin
  MeineKlasse := TMeineKlasse.Create;
showmessage (IntToStr (MeineKlasse.i));
  MeineKlasse.Destroy;
end.
Das Programm zeigt 2-mal '123' an, wie erwartet. Geht man dann noch hin und macht das IMHO überflüssige Destroy und alles was damit zusammenhängt weg, dann tut es das auch.

Wer hat ein Gegenbeispiel ? Es darf aber wirklich nur als Class deklariert sein. Das TObject-Free von Jason ist auch gemogelt, es geht um Destroy. Free hat eingebaute Funktionalität. Das ist schon was anderes.
Gruß
Hansa
  Mit Zitat antworten Zitat
IngoD7

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

Re: unsichtbare Klassen

  Alt 19. Feb 2007, 20:51
Moin Hansa,

das ist ungefähr das, was JasonDX meinte. Der direkte Aufruf von Destroy in deinem Beispiel verhält sich so, wie du sagst. Was anderes hatte JasonDX auch nicht behauptet.

Jetzt gibt es aber Fälle, wo (jetzt bezogen auf dein Beispiel) nicht
var MeineKlasse : TMeineKlasse; sondern
var MeineKlasse : TObject; gesetzt wird, und dennoch wie folgt created wird:
MeineKlasse := TMeineKlasse.Create; Jetzt erreicht dein Code den Destructor von TMeineKlasse nicht mehr.

Zitat von Hansa:
Das TObject-Free von Jason ist auch gemogelt, es geht um Destroy. Free hat eingebaute Funktionalität. Das ist schon was anderes.
Aber genau das ist gemeint!
Wer ruft denn bitteschön Destroy direkt auf? Für dein Beispiel war es jetzt ja ganz gut und schön und anschaulich. Aber in der Praxis sollte und wird die Methode Free oder die Procedure FreeAndNil() benutzt. Und genau dann ist override in jedem Fall erforderlich.
  Mit Zitat antworten Zitat
Hansa

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

Re: unsichtbare Klassen

  Alt 19. Feb 2007, 22:34
Zitat von IngoD7:
das ist ungefähr das, was JasonDX meinte. Der direkte Aufruf von Destroy in deinem Beispiel verhält sich so, wie du sagst. Was anderes hatte JasonDX auch nicht behauptet.
...
Gut, dann schmeiße ich das eigene Destroy mal selber raus. Da ist nicht mehr viel zu entfernen.

Delphi-Quellcode:
Unit Unit2;

interface

implementation

uses
  Dialogs,
  SysUtils;

type

TMeineKlasse = class
  private
    i : integer;
    constructor Create;
end;

var MeineKlasse : TMeineKlasse;

constructor TMeineKlasse.Create;
begin
  i := 123;
end;

begin
  MeineKlasse := TMeineKlasse.Create;
showmessage (IntToStr (MeineKlasse.i));
end.
Kein Destroy mehr, auch kein override und es geht immer noch. Ich will lediglich wissen, was einige hier vorhaben mit override etc. Und sieh mal einer an, was steht denn da :

Delphi-Quellcode:
constructor TObject.Create;
begin
end;
Da ist ja sogar das Create eventuell fällig.

Edit : es sei angemerkt, dass nicht mal inherited verwendet wird ! Normalerweise wäre das schon nötig.
Gruß
Hansa
  Mit Zitat antworten Zitat
IngoD7

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

Re: unsichtbare Klassen

  Alt 19. Feb 2007, 22:53
Zitat von Hansa:
Zitat von IngoD7:
das ist ungefähr das, was JasonDX meinte. Der direkte Aufruf von Destroy in deinem Beispiel verhält sich so, wie du sagst. Was anderes hatte JasonDX auch nicht behauptet.
...
Gut, dann schmeiße ich das eigene Destroy mal selber raus. Da ist nicht mehr viel zu entfernen.
Darum geht es doch gar nicht.

Du willst wissen, wie es sich mit virtuellen Methoden und override verhält? Fein. Steht hier in diesem Thread jetzt doppelt und dreifach. Lies in. In der Hilfe steht das ebenfalls recht ansprechend beschrieben. Die Geschichte mit Free ist zudem ein sehr schönes Beispiel für die Implemetierung in einer Klassenhierarchie. Kann man herrlich ausprobieren und (auch wenn's schwer ist) verstehen. Tue es, oder lass es. Ich habe keinen Bock, dir zu erklären, dass das Gras grün ist.

Wenn du jede Klasse ausschließlich so instantiierst wie sie deklariert ist 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.

Oder um auf das Gras zurückzukommen: Wenn du dein ganzen Grundstück zupflasterst, ist das in Ordnung. Die Rasenflächen der Anderen sind aber immer noch grün - ganz egal, ob du das akzeptierst oder nicht.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 3 von 4     123 4      


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 08:19 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