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);