请参见下面的代码。为了简单起见,我删除了很多代码,但是剩余的代码仍然很长,对不起:(
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;
然后在某个时候:
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;
最后,在某个时候:
var
MyClient: TClientClass;
begin
MyClient:=TClientClass.Create();
MyClient.Add(TRangePointModification.Create());
MyClient.Free;
end;
释放MyClient
时,将调用TClientClass
析构函数,然后应该清除内部fList
,但是TRangePointModification
的析构函数(来自{{1} })不被调用。 为什么不呢?
(我正在使用Delphi 10.2 Tokyo)
答案 0 :(得分:14)
查看警告-编译器会告诉您什么地方出错了:
W1010 Method 'Destroy' hides virtual method of base type ...
始终将override
放在析构函数上(不是虚拟的!),否则对Free
的调用将不会执行您放入析构函数中的代码。
因此,作为基本建议:
总是编写产生零警告或提示的代码-它们很可能指向您迟早会遇到的缺陷
将断点放入您怀疑有缺陷的代码中-即使忽略编译器警告,您甚至都不会调用Clear