【问题标题】:Delphi: TObjectList won't free object after Delete() is calledDelphi:调用 Delete() 后 TObjectList 不会释放对象
【发布时间】:2020-06-26 18:39:45
【问题描述】:

我有一个TObjectList<TUSBDevice>,其中TUSBDevice 是我创建的一个类。我尝试使用作为参数传递的索引调用Delete,但它只是做了TList.Delete() 所做的事情:从列表中删除指针但不释放对象本身。

我在TUSBDevice.Destroy() 上放置的断点在调用Delete() 时不会中断。我在TObjectList 上也有手表,我可以看到该项目已从列表中删除,但该对象的内存地址处的内容并未被释放。

TUSBDevice的析构函数:

destructor TUSBDevice.Destroy();
begin
  removeDatabaseEntry();
  filteredFolders.Free();
  fileQueue.Free();
end;

【问题讨论】:

  • 请提供minimal reproducible example您的问题没有足够的信息来重现您的问题。
  • 您可能忘记用override 标记TUSBDevice 析构函数声明:destructor Destroy; override;。或者您的对象列表不拥有其成员。
  • 这是安德烈亚斯的问题,谢谢。我总是忘记我需要这样做。

标签: delphi destructor rad-studio tlist tobjectlist


【解决方案1】:

无法回答您的问题,因为它不包含最小的可重现示例;问题不在于您发布的代码,而在于其他地方。

不过,“被覆盖”的析构函数没有运行的最常见原因是它实际上没有被覆盖。所以我几乎可以打赌你的Destroy 声明缺少override

TUSBDevice = class
  // ...
public
  // ...
  destructor Destroy; override;
  // ...
end;

【讨论】:

  • 让我的构造函数也被覆盖是个好主意吗?
  • 这取决于几个因素。一个类可以有多个构造函数,而TObject 构造函数不是虚拟的,因此它不能被覆盖。所以,如果基类是TObject,你就没有什么可以覆盖的了。另一方面,如果基类是TDevice,并且该基类具有必须运行的虚拟构造函数才能正确初始化对象,并且您的新构造函数具有相同的参数列表,那么这是一个好主意。当然,不要忘记调用inherited 构造函数(以及继承的析构函数,至少如果它不是空的TObject.Destroy)。
  • 通常,重写的构造函数 inherited; 开头,重写的析构函数 inherited; 结尾。
  • 总是包含对继承的构造函数和析构函数的调用。这样,如果您选择更改父类,您的代码就不会意外中断。
  • 我同意@DavidHeffernan。最好总是调用继承的构造函数或析构函数。
猜你喜欢
  • 2011-09-24
  • 2017-07-06
  • 1970-01-01
  • 2021-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-07
  • 1970-01-01
相关资源
最近更新 更多