An object in a TObjectList is not freed when a TObjectList.Clear is called

  • A+
Category:Languages

See the code below. I was removed a lot of code for the sake of simplicity, however the remaining code is still quite long, sorry :(

  IObserver = interface     ['{1DD212F8-BD5E-47BF-9A3B-39EF7B9D99B5}']     procedure Update(Observable: IObservable);   end;    TObserver = class abstract (TSingletonImplementation, IObserver)     strict protected       //...     public       constructor Create;       destructor Destroy; virtual;       //IObserver       procedure Update(Observable: IObservable); virtual; abstract;       //...    end;    TShapeModification = class abstract (TObserver)     strict protected       //...     public       //Doesn't have a constructor   end;    TRangePointModification = class(TShapeModification)     strict private       //...     public       constructor Create(...);       //...   end;    constructor TRangePointModification.Create(...);   begin     inherited Create;     //...   end; 

Then at some point:

TClientClass = class   strict private     fList: TObjectList<TShapeModification>;   public     constructor Create();     destructor Destroy(); override;     procedure Add(ShapeModification: TShapeModification); end;  constructor TClientClass.Create; begin   Self.fList:=TObjectList<TShapeModification>.Create(true); end;  destructor TClientClass.Destroy; begin   Self.fList.Clear;   FreeAndNil(Self.fList); end; 

Finally, at some point:

var   MyClient: TClientClass; begin   MyClient:=TClientClass.Create();   MyClient.Add(TRangePointModification.Create());   MyClient.Free; end; 

When the MyClient is freed, the TClientClass destructor is called then the internal fList is supposed to be cleared but the destructor of TRangePointModification (from TObserver) is not called. WHY not?

(I am using Delphi 10.2 Tokyo)

 


Look into the warnings - compiler tells you what is wrong:

W1010 Method 'Destroy' hides virtual method of base type ... 

Always put override on your destructors (not virtual!)- otherwise the call to Free will not execute the code you put into them.

So as a basic advice:

  1. always write code that produces zero warnings or hints - they most likely point to a defect that you will encounter sooner or later

  2. put a breakpoint into code you suspect to be defect - even when ignoring the compiler warning you would have seen the call to Clear was never even made

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: