Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.235.226.14] |
|
Страницы: (4) [1] 2 3 ... Последняя » все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
Для хранения динамических массивов, как свойств класса написал такой класс TIntegerValues64:
type TInt64_1DArray = array of Int64; TIntegerValues64 = class private fArray: TInt64_1DArray; function GetCount(): Integer; procedure SetCount(const Value: Integer); function GetArray(Index: Integer): Int64; procedure SetArray(Index: Integer; Value: Int64); public property Elements[Index: Integer]: Int64 read GetArray write SetArray; default; property Count: Integer read GetCount write SetCount; procedure Add(const aValue: Int64); procedure Destroy; procedure Free; end; Два вопроса: 1) Как правильно написать методы Create, Destroy и Free? 2) Не изобрел ли я велосипед? Это, ведь, очень похоже на TStringList, только про int64. Неужели нет в Delphi готового класса? Листинг метода Add: procedure TIntegerValues.Add(const aValue: integer); begin SetLength(fArray, Length(fArray)+1 ); FArray [Length(fArray)-1] := aValue; end; |
Сообщ.
#2
,
|
|
|
Free вообще писать не нужно.
Destroy - не просто процедура, а destructor Конструктор и деструктор нужны, если требуется какая-то инициализация и финализация. >SetLength(fArray, Length(fArray)+1 ); Так делать невыгодно - затраты памяти и времени будут велики. Стоит при необходимости увеличивать размер сразу вдвое или по крайней мере на значительно количество элементов. Вообще смысла в этом классе пока немного. Просто массив позволяет делать все то же самое, никаких особых удобств класс не добавляет. Если есть дополнительные соображения, расскажи. |
Сообщ.
#3
,
|
|
|
Для очистки динамического массива используется процедура Finalize.
|
Сообщ.
#4
,
|
|
|
Цитата MBo @ Destroy - не просто процедура, а destructor Да еще и виртуальный, так что override написать не забыть. destructor Destroy; override; А Free уже написан в TObject. |
Сообщ.
#5
,
|
|
|
Цитата Вообще смысла в этом классе пока немного. Просто массив позволяет делать все то же самое Просто массив не может быть свойством, только полем. Если сделать его свойством, то не будет поэлементного доступа к его элементам. Цитата Destroy - не просто процедура, а destructor Мне стыдно Переделал: TIntegerValues64 = class private fArray: TInt64_1DArray; function GetCount(): Integer; procedure SetCount(const Value: Integer); function GetArray(Index: Integer): Int64; procedure SetArray(Index: Integer; Value: Int64); public property Elements[Index: Integer]: Int64 read GetArray write SetArray; default; property Count: Integer read GetCount write SetCount; procedure Add(const aValue: Int64); destructor Destroy; override; //procedure Free; _DELETED FROM IMPLEMENTATION end; implementation destructor TIntegerValues64 .Destroy; begin Finalize(fArray); inherited destroy; end; Проблема при вызове метода Free не выполняется деструктор моего объекта и указателю на объект не присваивается nill |
Сообщ.
#6
,
|
|
|
Цитата ttiger @ Finalize(fArray); Не нужно, динамический массив финализируется при уничтожении объекта автоматически. А следовательно, можешь вообще деструктор не перекрывать, так как у тебя там только inherited. Цитата ttiger @ при вызове метода Free не выполняется деструктор моего объекта Не может быть. Или ты нам чего-то недоговариваешь, или твой вывод неверный. Цитата ttiger @ и указателю на объект не присваивается nill И не должен. |
Сообщ.
#7
,
|
|
|
>Просто массив не может быть свойством, только полем. Если сделать его свойством, то не будет поэлементного доступа к его элементам
класс TIntegerValues64 в таком виде не несет полезной нагрузки. Если нужно индексированное свойство типа Int64 в каком-то действительно полезном классе, то и делай приватное поле - массив, индексированное свойство, геттер и сеттер. Создавать новую сущность я особого смысла не вижу. |
Сообщ.
#8
,
|
|
|
Цитата и делай приватное поле - массив, индексированное свойство, геттер и сеттер. Создавать новую сущность я особого смысла не вижу. В классе, где используются эти свойства, таких две штуки публичных и три приватных. Пять раз писать сеттер и пять раз геттер, прибавляя к ним процедуру добавления в конец - это вообще, нормально? А если одна ошибка п китайском коде? Распечатывать модуль и ВСЕ перечитывать? Добавлено Цитата --Ins-- @ Цитата (ttiger @ Сегодня, 11:34) и указателю на объект не присваивается nill И не должен. Упс... У меня логика в методе следующая: в одном из свойств хранятся результаты подсчетов, притом они простои терируются. Перед тем, как повторно запускать подсчитывающий метод я "освобождаю" и снова создаю объект желаю таким образом очистить существующий, если есть и создать новый. Без явных доп. проверок. |
Сообщ.
#9
,
|
|
|
>Пять раз писать сеттер и пять раз геттер, прибавляя к ним процедуру добавления в конец - это вообще, нормально
ОК, разумно. На больше подробностей пока раскрутить не удалось |
Сообщ.
#10
,
|
|
|
Главный вопрос был в том, не изобрел ли я велосипед.
Хотелось удобства добавления в конец массива как в StringList. Раз все молчат, значит, не изобрел. Уже хорошо, а то месяц мучаюсь этим вопросом. Навероное, мне нужен метод FreeAndNill. Как его правильно написать для моего класса? |
Сообщ.
#11
,
|
|
|
Вообще-то это процедура такая, FreeAndNil:
var Obj: TSomeClass; ... Obj := TSomeClass.Create; ... FreeAndNil(Obj); // рекомендуется использовать везде, где это возможно, вместо Obj.Free; |
Сообщ.
#12
,
|
|
|
Цитата CodeMonkey @ // рекомендуется использовать везде, где это возможно, вместо Obj.Free; Странная рекомендация, если рассматривать ее не в контексте задачи а глобально. Цитата ttiger @ Навероное, мне нужен метод FreeAndNill. Как его правильно написать для моего класса? Такого метода быть не может в принципе. Объект не может изменить Self так, чтобы эти изменения сказались снаружи вызова. К тому же, объект один, а ссылок на него может быть масса. Объект о них не знает ничего. Как он может их обнулить? Не путай сам объект и переменную, которая хранит на него ссылку. |
Сообщ.
#13
,
|
|
|
Цитата ttiger @ Главный вопрос был в том, не изобрел ли я велосипед. До D2009 - точно нет. В D2009 вместо самописного списка можно использовать TList<Int64>. Цитата --Ins-- @ Странная рекомендация Эээ.. чем? |
Сообщ.
#14
,
|
|
|
Цитата CodeMonkey @ Эээ.. чем? Ну, ты пишешь что рекомендуется использовать везде, а я этого не понимаю. Поясни |
Сообщ.
#15
,
|
|
|
Ну причина проста - нет никаких доводов так не делать Зато есть доводы против использования Free (ниже).
Можно возразить, что, к примеру, это не всегда строго необходимо - как, например, при удалении локальных переменных. Однако как раз к такому аргументу есть следующие возражения: 1). Локальную переменную могут потом сделать глобальной или частично-глобальной. FreeAndNil защитит нас от double-free. Просто Free - нет. 2). Очень большое количество кода получается использованием copy-paste. Если стоит Free, то, скопировав код в другое место (где у переменной другая область видимости) мы можем получить проблемы. С FreeAndNil таких проблем нет. 3). Единообразие стиля. Удобно, когда везде написано FreeAndNil вместо помеси Free/FreeAndNil. И сам не запутаешься, когда что ставить ("ааа, здесь надо FreeAndNil или можно просто Free?!!"). 4). Экономия одного нескольких байт и одного лишнего вызова процедуры (т.е. если заменить FreeAndNil обратно на Free) не является аргументом в современных приложениях. |