Delphi: TObjectList не освобождает объект после вызова Delete()

У меня есть TObjectList<TUSBDevice>, где TUSBDevice — класс, который я создал. Я попытался вызвать Delete с индексом, переданным в качестве параметра, но он просто делает то, что делает TList.Delete(): удаляет указатель из списка, но не освобождает сам объект.

Точка останова, которую я поставил на TUSBDevice.Destroy(), не прерывается при вызове Delete(). У меня также были часы на TObjectList, и я вижу, что элемент удаляется из списка, но содержимое по адресу памяти объекта не освобождается.

Деструктор TUSBDevice:

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

person Radu M.    schedule 15.03.2020    source источник
comment
Предоставьте минимальный воспроизводимый пример В вашем вопросе как есть недостаточно информации для воспроизведения вашей проблемы.   -  person Dalija Prasnikar    schedule 15.03.2020
comment
Вероятно, вы забыли пометить объявление деструктора TUSBDevice знаком override: destructor Destroy; override;. Или ваш список объектов не владеет своими членами.   -  person Andreas Rejbrand    schedule 15.03.2020
comment
Это была проблема, Андреас, спасибо. Я всегда забываю, что мне нужно это сделать.   -  person Radu M.    schedule 15.03.2020


Ответы (1)


Невозможно ответить на ваш вопрос, поскольку он не содержит минимального воспроизводимого примера; проблемы заключаются не в опубликованном вами коде, а в другом месте.

Тем не менее, наиболее распространенная причина того, что «переопределенный» деструктор не работает, заключается в том, что он на самом деле не переопределен. Так что я почти могу поспорить, что в вашем объявлении Destroy отсутствует override:

TUSBDevice = class
  // ...
public
  // ...
  destructor Destroy; override;
  // ...
end;
person Andreas Rejbrand    schedule 15.03.2020
comment
Было бы хорошей идеей сделать мой конструктор перекрытым? - person Radu M.; 15.03.2020
comment
Это зависит от нескольких факторов. У класса может быть несколько конструкторов, а конструктор TObject не является виртуальным, поэтому его нельзя переопределить. Итак, если базовый класс TObject, вам нечего переопределять. С другой стороны, если базовым классом является TDevice и у него есть виртуальный конструктор, который должен быть запущен для правильной инициализации объекта, и ваш новый конструктор имеет тот же список аргументов, то это хорошая идея. И, конечно же, не забудьте вызвать конструктор inherited (и унаследованный деструктор, по крайней мере, если это не пустой TObject.Destroy). - person Andreas Rejbrand; 15.03.2020
comment
Обычно переопределенный конструктор начинается с inherited;, а переопределяемый деструктор заканчивается на inherited;. - person Andreas Rejbrand; 15.03.2020
comment
Да, базовым классом TUSBDevice является TObject. Спасибо, это имеет смысл. - person Radu M.; 15.03.2020
comment
Всегда включайте вызов унаследованного конструктора и деструктора. Таким образом, ваш код не сломается неожиданно, если вы когда-нибудь решите изменить родительский класс. - person David Heffernan; 15.03.2020
comment
Я согласен с @DavidHeffernan. Лучше всего всегда вызывать унаследованный конструктор или деструктор. - person Andreas Rejbrand; 15.03.2020