При работе с библиотекой компонентов Delphi 7 пользователь столкнулся с проблемой создания списка TList для элементов типа Extended. В процессе реализации класса TAExtList для работы со списком значений типа Extended, возникла ошибка некорректного приведения типов, несмотря на успешное использование подобного приведения для списков целых чисел и цветов.
Проблема
В коде класса TAExtList используется приведение типов для добавления элементов в список TList, что успешно работает для целых чисел и цветов, но вызывает ошибку при работе со значениями типа Extended.
Type
TAExtList = Class(TObject)
Private
FList: TList;
Procedure SetExt(Index: Integer; Value: Extended);
Function GetCnt: Integer;
Function GetExt(Index: Integer): Extended;
Public
Constructor Create;
Destructor Destroy; Override;
Function Add(Value: Extended): Integer;
// ... другие методы ...
End;
Function TAExtList.Add(Value: Extended): Integer;
Begin
Result := FList.Add(Pointer(Value));
End;
Причины проблемы
Проблема заключается в том, что тип Extended в Delphi имеет размер 10 байт, в отличие от Pointer, который имеет размер 4 байта. Это несоответствие размеров приводит к ошибке приведения типов.
Решение
Для решения проблемы можно использовать указатели на Extended. В этом случае TList будет хранить указатели, а не сами значения. Пример реализации метода Add для класса TAExtList:
type
PExtended = ^Extended;
function TExtendedList.Add(const E: Extended): Integer;
var
P: PExtended;
begin
New(P); // выделение памяти для Extended на куче
P^ := E; // сохранение значения в выделенной памяти
Result := inherited Add(P); // добавление указателя в список
end;
При удалении элементов из списка или его очистке необходимо освобождать выделенную память:
procedure TExtendedList.Delete(Index: Integer);
begin
Dispose(PExtended(inherited Items[Index]));
inherited Delete(Index);
end;
procedure TExtendedList.Clear;
var
I: Integer;
begin
for I := 0 to Count - 1 do
Dispose(PExtended(inherited Items[I]));
inherited Clear;
end;
Также полезно переопределить виртуальный метод Notify для обработки удаления элементов:
procedure TExtendedList.Notify(Ptr: Pointer; Action: TListNotification);
begin
inherited;
if Action = lnDeleted then
Dispose(PExtended(Ptr));
end;
Альтернативное решение
В более новых версиях Delphi доступны обобщенные типы (generics), которые позволяют создать TList<Extended> и избежать подобных проблем.
Заключение
Использование указателей на Extended позволяет создать список значений этого типа в Delphi 7. Однако, стоит учитывать, что работа с динамическими массивами указателей может быть менее эффективной по сравнению с использованием динамических массивов. В новых версиях Delphi рекомендуется использовать обобщенные типы для создания списков с различными типами элементов.
Пользователь столкнулся с проблемой создания `TList` для элементов типа `Extended` в Delphi 7, связанной с некорректным приведением типов при использовании стандартных методов класса `TList`.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.