Вопрос, поднятый пользователем в контексте, заключается в проблеме с использованием умных указателей в Delphi 10.3 Rio с использованием библиотеки Spring4D. Пользователь столкнулся с тем, что при добавлении объектов в TObjectList, предыдущий объект удалялся, что было заметно по выводу программы. Основная проблема заключалась в неправильном хранении объектов в списке.
Подробное описание проблемы
Пользователь создал обобщенный TObjectList и пытался добавить в него объекты типа TObject с использованием функции Shared.Make<TTestObj.Create>(). Однако, при каждом добавлении нового объекта в список, предыдущий объект освобождался. Это поведение было заметно по выводу программы, в котором сообщалось о уничтожении объектов.
Пример кода, вызывающего проблему
program TestSmartPointer;
{$APPTYPE CONSOLE}
uses
Spring,
Diagnostics,
Classes,
SysUtils,
System.Generics.Collections;
type
TTestObj = class
private
FDescription: string;
public
property Description: string read FDescription write FDescription;
destructor Destroy; override;
end;
TTestList = class(TObjectList<TTestObj>)
destructor Destroy; override;
end;
var
LISTITEMCOUNT: integer;
LISTCOUNT: integer;
procedure Test_SmartPointer;
begin
Writeln('SmartPointer test started');
var lTestList := Shared.Make(TTestList.Create)();
lTestList.OwnsObjects := false;
for var i := 1 to 10 do
begin
var lTestObj := Shared.Make(TTestObj.Create)();
lTestObj.Description := i.ToString;
Writeln('TestObj added to Testlist with description ' + lTestObj.Description);
lTestList.Add(lTestObj);
end;
Writeln('SmartPointer test finished');
end;
...
begin
Test_SmartPointer;
Readln;
end.
Подтвержденный ответ и его объяснение
Проблема заключалась в том, что TObjectList хранил сырые указатели на объекты TTestObj, а не интерфейсы IShared<TTestObj>, возвращаемые функцией Shared.Make<T>().
Для решения проблемы нужно изменить TTestList так, чтобы он хранил элементы типа IShared<TTestObj>, а не TTestObj. В этом случае следует использовать TList<IShared<T>> вместо TObjectList<T>.
Вот исправленный код:
program TestSmartPointer;
{$APPTYPE CONSOLE}
uses
Spring,
Diagnostics,
Classes,
SysUtils,
System.Generics.Collections;
type
TTestObj = class
private
FDescription: string;
public
property Description: string read FDescription write FDescription;
destructor Destroy; override;
end;
TTestList = class(TList<IShared<TTestObj>>)
destructor Destroy; override;
end;
...
procedure Test_SmartPointer;
begin
Writeln('SmartPointer test started');
var lTestList := Shared.Make(TTestList.Create);
for var i := 1 to 10 do
begin
var lTestObj := Shared.Make(TTestObj.Create);
lTestObj.Description := i.ToString;
Writeln('TestObj added to Testlist with description ' + lTestObj.Description);
lTestList.Add(lTestObj);
end;
Writeln('SmartPointer test finished');
end;
...
begin
Test_SmartPointer;
Readln;
end.
Альтернативный ответ и дополнительные замечания
Пользователь также упоминал, что искал простую структуру для автоматического освобождения объектов, и умные указатели показались ему слишком сложными для этой цели. Однако, после получения ответа от Remy Lebeau, пользователь понял, что проблема заключалась в неправильном использовании функции Shared.Make<T>().
Заключение
Использование умных указателей в Delphi с помощью Spring4D может быть мощным инструментом, но требует правильного понимания того, как работают интерфейсы IShared<T>. При правильном подходе, умные указатели могут обеспечить автоматическое управление памятью и освобождение объектов, когда они больше не используются.
Пользователь столкнулся с проблемой при использовании умных указателей в Delphi 10.3 Rio с библиотекой Spring4D, связанной с неправильным хранением объектов в `TObjectList`, что приводило к их удалению при добавлении новых объектов.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.