Советы по Delphi. Версия 1.4.3 от 1.1.2001 - страница 19
Лично я инкапсулировал все в своем объекте. Я использую, как я это называю, «Basic String Object» (BSO), базовый строковый объект, который осуществляет динамическое распределение и освобождение памяти для строк любого размера. Непосредственно это PChar, указывающий на распределенную память. У меня существует два внешних свойства: AsString и AsPChar. Также у меня есть различные свойства и методы, позволяющие иметь различные способы доступа и манипулировать строками.
Я написал свои собственные malloc(), calloc() и realloc(), используя частные методы объекта TString для сканирования распределенной памяти. Это классно работает, когда мне нужно «захватить» блок памяти.
С помощью двух методов я могу распределить необходимую мне память (блоками, так что это не занимает много процессорного времени), и освобождать ее (когда существует определенный резерв – и снова так, чтобы не тратить много процессорного времени).
О другой идее я уже рассказывал (открытый массив). Если вам нужна проверка выхода за границы и/или динамическое изменение размера массива, вы можете использовать метод, аналогичный методу работы со строковым объектом (описанный мною выше), но вам необходимо будет интегрировать свойство-массив по умолчанию, чтобы иметь к нему простой доступ. Это позволит вам иметь индексы и использовать нужный вам тип.
>TMyDynamicObject =
> …
> PROPERTY Array[idx:LONGINT]:TMyType READ GetArray WRITE PutArray DEFAULT;
>…
>VAR Mine :TMyDynamicObject;
>…
>Mine := TMyDynamicObject.Create;
>FOR i := 10 TO 20 DO Mine[i] := {значение}
>{ЧУДОВИЩНАЯ РАСТРАТА ПАМЯТИ - если вы действительно используете такие большие массивы и хэш-таблицы }
>Mine[-100000] := {значение}
>Mine[+100000] := {значение}
Если в вашем распоряжении находится «редкозаполненный» массив, использование хэш-таблицы дало бы существенный выигрыш. Я преобразую индексные значения в строки, а все остальное перепоручаю TStrings, но не из-за того, что я такой ленивый, а из-за того, что он сделает это лучше меня, мне нужно всего лишь осуществить преобразование в строки.
Для того, чтобы хранить все, что вы хотите, вы можете использовать TList (или TStringList.Objects)! TList.Items хранят указатели на объекты или записи, но они ничего не могут сделать с ними, поэтому вы можете привести их к типу longint, и больше о них не беспокоиться! Вот пример хранения в TList списка целых:
>var
> aList: TList;
> I : Integer;
> L : Longint;
>begin
> aList := TList.Create;
> L := 93823;
> aList.Add(Pointer(L));
> aList.Add(Pointer(83293));
> for I := 1 to aList.Count do L := L + Longint(aList.Items[I-1]);
> aList.Free;
>end;
В TList и TStringList вы можете иметь до 16380 элементов. А теперь обещанный пример того, как можно хранить в TList записи (или объекты), вернее, указатели на них:
>type
> PMyRec = TMyRec;
> TMyRec = record
> Name: string[40];
> Addr : string[25];
> Comments: string;
> salary: Double;
> end;
>var
> aList: TList;
> aRecPtr: PMyRec;
> I : Integer;
>begin
> aList := TList.Create;
> New(aRecPtr);
> with aRecPtr^ do begin
> Name := 'Валентин';
> Addr := 'неизвестен';
> Comments := 'Автор Советов по Delphi';
> Salary := 999000.00;
> end;
> aList.Add(aRecPtr);
> aList.Add(…);
> …
> for I := 1 to aList.Count do begin
> aRecPtr := PMyRec(aList.Items[I-1]);
> {что-то делаем с записью}
> end;
> {теперь избавляемся от всех записей и самого списка-объекта}
> for I := 1 to aList.Count do Dispose(PMyRec(aList.Items[I-1]));
> aList.Free;
>end;
Динамические массивы VIII
Иногда разработчик, работая с массивами, не знает какого размера массив ему нужен. Тогда Вам пригодится использование динамических массивов.
>var intArray : array of integer;
При таком объявлении размер массива не указывается. Что бы использовать его дальше необходимо определить его размер (обратите внимание, что размер динамического массива можно устанавливать в программе):
>begin
> intArray:=(New(IntArray,100); //Размер массива? 100
>end;
Пример массива констант (Array of Const) III
Delphi 1
>procedure foo(a : array of const);
>implementation
> var
> var1: longint;
> var2: pointer;
> var3: integer;
>begin
> var1 := 12345678;
> var2 := @var1;
> var3 := 1234;