Delphi-PRAXiS
Seite 1 von 2  1 2   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Klasse in einer Klasse Destruktor (https://www.delphipraxis.net/204210-klasse-einer-klasse-destruktor.html)

kagi3624 7. Mai 2020 07:50

Delphi-Version: 6

Klasse in einer Klasse Destruktor
 
Wenn ich eine Klasse in einer anderen Klasse instanziere, wird diese Unterklasse zerstört, wenn ich die Oberklasse vernichte, oder muss ich einen extra destruktor für schreiben?

Code:

Bar = class
...

Foo = class
fBar : Bar;

constructor Create;
end
...
constructor Foo.Create;
begin
 fBar := Bar.create;
end;

hoika 7. Mai 2020 07:58

AW: Klasse in einer Klasse Destruktor
 
Hallo,
in diesem Fall musst du das selber machen.

Anders wäre es, wenn du einen Owner einführen würdest (wie das bei den Komponentenklassen ist).

Das muss du aber erst mal selber programmieren,
oder du leitest Deine Basisklasse gleich von TComponent ab.

FastMM4 sagt dir schon (Stichwort ReportMemoryLeaksOnShutDown), ob du ein Speicher-Leck hast.

kagi3624 7. Mai 2020 08:08

AW: Klasse in einer Klasse Destruktor
 
Ok, reicht es wenn ich in der Foo Klasse in dem Destructor dann

fBar.Free; habe?

Der schöne Günther 7. Mai 2020 08:26

AW: Klasse in einer Klasse Destruktor
 
Ganz genau. Der Destruktor wird auch immer ausgeführt, auch wenn der Konstruktor scheiterte, z.B. eine Exception auftritt.

Rollo62 7. Mai 2020 08:31

AW: Klasse in einer Klasse Destruktor
 
Ja, das reicht.

Ich resette/cleare zusätzlich vorher immer noch mögliche Referenzen, Threads, oder Sonstiges, z.B. Events von Aussen, Asynchrone Abfragen oder was Deine Klasse sonst noch Alles anstellt.
Damit nicht noch kurz vor oder nach dem .Free irgendwas Gemeines in deinem Objekt weiterlebt.

kagi3624 7. Mai 2020 08:34

AW: Klasse in einer Klasse Destruktor
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1463873)
Ganz genau. Der Destruktor wird auch immer ausgeführt, auch wenn der Konstruktor scheiterte, z.B. eine Exception auftritt.

Ich habe aber gerade gesehen, dass mein destructor nicht (explicit) ? aufgerufen wird, wenn ich nur Foo.Free; habe. Erst wenn ich ein override; hinter dem Destructor habe, wird dieser mit Free aufgerufen.

Der schöne Günther 7. Mai 2020 08:44

AW: Klasse in einer Klasse Destruktor
 
Destruktoren sind in Delphi quasi als virtuelle Methode implementiert. Du hättest da auch eigentlich eine Compiler-Warnung bekommen müssen.

Hier einmal als Minimalbeispiel zum Ausprobieren:

Delphi-Quellcode:
program Project1;

{$APPTYPE CONSOLE}
{$R *.res}

uses System.SysUtils;

type
   TMyObject = class
      destructor Destroy(); {override;}
   end;

destructor TMyObject.Destroy();
begin
   inherited;
end;

var
   myObject: TObject;
begin
   myObject := TMyObject.Create();
end.

Rollo62 7. Mai 2020 08:51

AW: Klasse in einer Klasse Destruktor
 
Delphi-Quellcode:
var
   myObject: TObject;
begin
   myObject := TMyObject.Create();
   ...
   myObject.Free; //<===
end.
Das würde ich noch ergänzen, damit das Free -> Destroy klar wird.

kagi3624 7. Mai 2020 09:02

AW: Klasse in einer Klasse Destruktor
 
Hmm..was macht denn das 'inherited' in dem Destruktor? Es wird doch von keienr Klasse geerbt?

Der schöne Günther 7. Mai 2020 09:13

AW: Klasse in einer Klasse Destruktor
 
Alle Delphi-Klassen stammen von TObject ab. Das TObject bringt sowohl den Standard-Konstruktor
Delphi-Quellcode:
Create()
als auch den Standard-Destruktor
Delphi-Quellcode:
Destroy()
mit.

Wenn du einen eigenen Destruktor hast, dann solltest du auch wirklich immer ein
Delphi-Quellcode:
inherited
drin haben. Ja, wenn man seine Klasse direkt von
Delphi-Quellcode:
TObject
ableitet könnte man es sich sparen. Aber warum nicht? Angenommen deine Klasse
Delphi-Quellcode:
TMySpecialization
hat sich ursprünglich nicht von TMyBase abgeleitet, jetzt aber schon. Und du hättest in deinem Destruktor von
Delphi-Quellcode:
TMySpecialization
das
Delphi-Quellcode:
inherited
nicht drin gehabt. Dann hättest du jetzt ein Speicherleck (oder eventuell schlimmeres) da der Destruktor von
Delphi-Quellcode:
TMyBase
(und allem darüber) nicht mehr ausgeführt würde.

Delphi-Quellcode:
type
  TMyBase = class // man könnte ebenso schreiben "TMyBase = class(TObject)"
    private var
      someStuff: TObject;
    public
      constructor Create();
      destructor Destroy(); override;
  end;

  TMySpecialization = class(TMyBase)
    public
      constructor Create();
      destructor Destroy(); override;
  end;

{ TMySpecialization }

constructor TMySpecialization.Create();
begin
  inherited; // sowas von überhaupt nicht überflüssig
  // (...)
end;

destructor TMySpecialization.Destroy();
begin
  // (...)
  inherited; // sowas von überhaupt nicht überflüssig
end;

{ TMyBase }

constructor TMyBase.Create();
begin
  inherited; // streng genommen überflüssig, aber warum nicht?
  someStuff := TObject.Create();
end;

destructor TMyBase.Destroy();
begin
  someStuff.Free();
  inherited; // GANZ streng genommen überflüssig, aber warum nicht?
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:35 Uhr.
Seite 1 von 2  1 2   

Powered by vBulletin® Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2020 by Daniel R. Wolf