Objektfreigabe

Aus RAD Studio
Wechseln zu: Navigation, Suche

Nach oben zu C++- und Object Pascal-Modelle


Zwei die Objektfreigabe betreffende Mechanismen arbeiten in C++ anders als in Object Pascal. Dies sind:

  • Destruktoren, die wegen von Konstruktoren ausgelösten Exceptions aufgerufen werden
  • Virtuelle Methoden, die von Destruktoren aufgerufen werden

Klassen im Delphi-Stil kombinieren die Methoden der beiden Sprachen. Diese Themen werden im Folgenden behandelt.

Von Konstruktoren ausgelöste Exceptions

Destruktoren werden in C++ anders als in Object Pascal aufgerufen, wenn eine Exception während der Objekterstellung ausgelöst wird. Ein Beispiel: Die Klasse C ist von der Klasse B abgeleitet, die selbst von der Klasse A abgleitet ist:

 class   A { 
 
 // Rumpf 
 } ; 
 
 class  B:  public   A { 
 
 // Rumpf 
 } ; 
 
 class  C:  public   B 
 { 
 
 // Rumpf 
 } ;

Angenommen, eine Exception wird im Konstruktor der Klasse B beim Erstellen einer Instanz von C ausgelöst. Die Ergebnisse dieser Situation in C++, Object Pascal und für Klassen im Delphi-Stil werden im Folgenden beschrieben:

  • In C++ werden zuerst die Destruktoren aller vollständig erstellten Objektdaten-Member von B aufgerufen, dann der Destruktor von A und dann die Destruktoren aller vollständig erstellten Daten-Member von A. Die Destruktoren für B und C werden aber nicht aufgerufen.
  • In Object Pascal wird nur der instantiierte Klassendestruktor automatisch aufgerufen. Das ist der Destruktor für C. Wie bei Konstruktoren obliegt es dem Programmierer, inherited in Destruktoren aufzurufen. In diesem Beispiel wird davon ausgegangen, dass alle Destruktoren inherited aufrufen, dann werden die Destruktoren für C, B und A (in dieser Reihenfolge) aufgerufen. Unabhängig davon, ob inherited bereits im Konstruktor von B aufgerufen wurde, bevor die Exception auftrat, wird zudem der Destruktor von A aufgerufen, weil inherited im Destruktor von B aufgerufen wurde. Der Aufruf des Destruktors für A ist unabhängig davon, ob sein Konstruktor tatsächlich aufgerufen wurde. Wichtiger ist aber, dass - weil Konstruktoren in der Regel inherited sofort aufrufen -, der Destruktor für C aufgerufen wird, ob nun der Rumpf des Konstruktors vollständig ausgeführt wurde oder nicht.
  • Bei Klassen im Delphi-Stil rufen die VCL-, FireMonkey- und RTL-Basisklassen (implementiert in Object Pascal) die Destruktoren genauso wie in Object Pascal auf. Die abgeleiteten Klassen (implementiert in C++) folgen nicht genau dem Vorgehen einer der beiden Sprachen. Alle Destruktoren werden aufgerufen; aber die Rümpfe derjenigen, die gemäß der C++-Sprachregeln nicht aufgerufen worden wären, werden nicht ausgeführt.

Die in Object Pascal implementierten Klassen stellen so eine Möglichkeit bereit, Bereinigungscode im Rumpf des Destruktors zu verarbeiten. Dazu gehört Quelltext, der den Speicher für Unterobjekte (Daten-Member, die Objekte sind) freigibt, die vor einer Konstruktor-Exception erstellt wurden. Bei Klassen im Delphi-Stil wird aber der Bereinigungscode für die instantiierte Klasse oder ihre in C++ implementierten Basisklassen möglicherweise nicht verarbeitet, obwohl die Destruktoren aufgerufen wurden.

Virtuelle Methoden, die von Destruktoren aufgerufen werden

Die Bindung virtueller Methoden in Destruktoren wird nach demselben Muster wie für Konstruktoren ausgeführt. Das bedeutet, dass bei Klassen im Delphi-Stil die abgeleitete Klasse zuerst freigegeben wird, der Laufzeittyp des Objekts bleibt aber während der folgenden Aufrufe der Basisklassendestruktoren derjenige der abgeleiteten Klasse. Wenn virtuelle Methoden in Bibliothek-Basisklassendestruktoren aufgerufen werden, binden Sie möglicherweise an eine Klasse, die sich bereits freigegeben hat.

Siehe auch