AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Tutorials [Tutorial] Den Destruktor verstehen
Tutorial durchsuchen
Ansicht
Themen-Optionen

[Tutorial] Den Destruktor verstehen

Ein Tutorial von sx2008 · begonnen am 15. Apr 2012 · letzter Beitrag vom 20. Apr 2012
Antwort Antwort
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.340 Beiträge
 
Delphi 12 Athens
 
#1

AW: [Tutorial] Den Destruktor verstehen

  Alt 15. Apr 2012, 11:04
Beim Destruktor ist das verboten! Die Kette der Destruktoren muss abgearbeitet werden; sie darf nicht unterbrochen werden. Falls doch, droht ein Resourcen-/Speicherleck.
Doch, ist es ... wenn ich den Constructor ebenfalls übergangen hab und/oder für die Freigaben selbst gesorgt hab.
(praktisch für einen Bugfix)

Zitat:
Resourcen (Speicher, Handles,...) sollten immer in umgekehrter Weise freigegeben werden, in der sie angefordert wurden; das ist der sicherste Weg.
Wenn das schon anders erstellt wurde, dann stimmt es auch wieder.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Benutzerbild von sx2008
sx2008

Registriert seit: 15. Feb 2008
Ort: Baden-Württemberg
2.332 Beiträge
 
Delphi 2007 Professional
 
#2

AW: [Tutorial] Den Destruktor verstehen

  Alt 17. Apr 2012, 05:55
Die Kette der Destruktoren muss abgearbeitet werden; sie darf nicht unterbrochen werden. Falls doch, droht ein Resourcen-/Speicherleck.
Doch, ist es ... wenn ich den Constructor ebenfalls übergangen hab und/oder für die Freigaben selbst gesorgt hab.
Nein, ein Destruktor einer Klasse hat eine ganz bestimmte Verantwortung:
1.) er muss die lokalen belegten Resourcen seiner Klasse freigeben!

2.) er muss die Resourcen freigeben, die seiner Klasse überantwortet wurden
Zum Beispiel übernimmt die Klasse TComponent die Verantwortung dafür, dass alle Objekte im Components[]-Array im Destruktor entsorgt werden.

3.) er muss seiner Vaterklasse die Möglichkeit geben sich selbst aufzuräumen in dem er inherited aufruft.
Was im Destruktor der Vaterklasse passiert und ob dessen Konstruktor aufgerufen wurde oder nicht hat nicht zu interessieren.
Der Sourcecode der Vaterklasse muss als Blackbox betrachtet werden;
es muss völlig egal sein was in der Vaterklasse an Resourcen belegt wurde oder nicht.
Wichtig ist allein nur der Vaterklasse über den Aufruf von inherited die Chance zu geben, alle belegten Resourcen zu entsorgen.

4.) er muss so programmiert sein, dass selbst wenn ein Objekt nur teilweise initialisiert wurde (z.B. Exception im Konstructor) er gefahrlos die bislang belegten Resourcen freigibt.

Das sind die Regeln; das ist der (ungeschriebene) Vertrag der bei Ableitung einer Klasse geschlossen wurde.
  Mit Zitat antworten Zitat
Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.487 Beiträge
 
Delphi 12 Athens
 
#3

AW: [Tutorial] Den Destruktor verstehen

  Alt 19. Apr 2012, 12:53
In 99,9% aller Fälle sind deine Regeln zutreffend, es kann Ausnahmefällen geben, allerdings sollte eine Regel immer eingehalten werden: Der Destructor "Destroy" muss immer in der Lage sein das Objekt korrekt freizugeben.

Ein kleines Beispiel mit Zirkelbezug:
Delphi-Quellcode:
TPartnerObject = class(TObject)
protected
  FPartner: TPartnerObject;
public
  // darf nicht mehr überschrieben werden
  destructor Destroy; override; finally;
  // kann in abgeleiteten Klassen überschrieben werden
  destructor MyDestroy(Sender: TObject); virtual;
  property Partner: TPartnerObject read FPartner write FPartner;
end;

// bleibt weiterhin voll funktionsfähig
destructor TPartnerObject.Destroy;
begin
  MyDestroy(Self);
end;

// Destroy ruft immer das für die Klasse gültige MyDestroy auf
destructor TPartnerObject.MyDestroy(Sender: TObject);
begin
  if Assigned(FPartner) and (FPartner <> Sender) then
    FPartner.MyDestroy(Sender);

  inherited Destroy;
end;


Kette := TPartnerObject.Create;
Kette.Partner := TPartnerObject.Create;
Kette.Partner.Partner := TPartnerObject.Create;
Kette.Partner.Partner.Partner := Kette;

FreeAndNil(Kette);
  Mit Zitat antworten Zitat
Benutzerbild von BUG
BUG

Registriert seit: 4. Dez 2003
Ort: Cottbus
2.094 Beiträge
 
#4

AW: [Tutorial] Den Destruktor verstehen

  Alt 20. Apr 2012, 00:00
Delphi-Quellcode:
Kreis := TPartnerObject.Create;
Kreis.Partner := TPartnerObject.Create;
Kreis.Partner.Partner := Kreis;
Stiel := TPartnerObject.Create;
Stiel.Partner = Kreis;
Stiel.free(); // Stackoverflow? (Ungetestet: hab grad kein Delphi zur Hand)
Wuhaha, Kreis am Stiel

Eine Variante, die auch dieses Problem lösen sollte:
Delphi-Quellcode:
TPartnerObject = class(TObject)
private
  FDieing: boolean;
protected
  FPartner: TPartnerObject;
public
  constructor Create;
  destructor Destroy; override;
  property Partner: TPartnerObject read FPartner write FPartner;
end;

constructor TPartnerObject.create;
begin
  FDieing := false;
  FPartner := nil;
end;

destructor TPartnerObject.Destroy;
begin
  FDieing := true;
  if assigned(Partner) then
    if not FPartner.Dieing then
      FPartner.Destroy; // ist schon auf nil überprüft
  inherited;
end;
Das würde bei auch mehreren Partnern funktionieren und entspricht der Tiefensuche in einem Graphen.
  Mit Zitat antworten Zitat
Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.487 Beiträge
 
Delphi 12 Athens
 
#5

AW: [Tutorial] Den Destruktor verstehen

  Alt 20. Apr 2012, 07:28
Natürlich gibt es für ein Problem immer mehrere Lösungen und in diesem konkreten Fall würde ich die Variante mit dem Flag vorziehen. Aber das ist nur ein Beispiel, das den richtigen Einsatz eines zweiten Destruktors demonstrieren soll.
  Mit Zitat antworten Zitat
Antwort Antwort


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 05:18 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-2025 by Thomas Breitkreuz