Иллюстрированный самоучитель по Turbo Pascal

Создание коллекций

После того как тем или иным способом определены типы данных, создание коллекции не вызывает проблем. Например:

var
BookList: PCollection;
begin
BookList: = New(PCollection, Init(50.10));
with BookList do
begin
Insert(New(PBook, Init('Джордейн Р.',
'Справочник программиста персональных компьютеров'+
' типа IBM PC, XT и AT','Финансы и статистика',
1991.544)));
Insert(New(PBook, Init('Шелдон',
'Язык Си для профессионалов','И.В.К.-СОФТ',1991.383))); Insert(New(PBook, Init('Скэнлон Л.',
'Персональные ЭВМ IBM PC и XT. '+
'Программирование на языке ассемблера',
'Радио и связь',1991.336)));
Insert(New(PBook,
Init('Йенсен К., Вирт Н.',
'Паскаль. Руководство для пользователя '+
'и описание языка','Финансы и Статистика',1982.151)));
end;
…..
Dispose(BookList, Done);
end;

Для создания коллекции мы обратились к методу TCollection.Init, указав ему начальную длину коллекции (50 элементов) и шаг наращивания (10 элементов). Руководствуясь этими указаниями, Turbo Vision зарезервирует в динамической памяти место для размещения 50 указателей. Если в ходе наполнения коллекции ее длина превысит начальную, Turbo Vision будет наращивать коллекцию порциями, каждая из которых достаточна для размещения 10 указателей.

Смысл параметров, передаваемых методу TCollection.Init, станет понятнее, если рассмотреть механизм создания и обновления коллекции. Вначале в куче резервируется участок памяти, достаточный для размещения массива из N0 указателей (N0 – начальный размер коллекции). Если в ходе наполнения коллекции ее длина превысит N0 элементов, резервируется новый участок памяти, достаточный для размещения массива из NO + DN указателей (DN – шаг наращивания коллекции), затем старый массив переносится на новое место, а память, выделенная под его размещение, возвращается в кучу. Таким образом, чем больше начальная длина коллекции и шаг ее наращивания, тем меньше суммарные потери времени на расширение коллекции, но и тем больше могут стать потери памяти, есди реальная длина коллекции окажется значительно меньше NO + k*DN (k = 0, 1, 2,…).

Операторы Insert размещают в динамической памяти элементы коллекции. В реальной программе наполнение коллекции будет, судя по всему, осуществляться каким-то иным способом, чем простое программирование обращений к методу Insert (см., например, программу Notebook из гл.15). Для нас сейчас важно другое: мы нигде не говорили коллекции, какого типа объекты она будет хранить; для обеспечения нужных действий по размещению в памяти очередного элемента мы просто обращаемся к соответствующему методу Init, а уж он делает остальное – ведь он "знает" как это следует сделать.

Отметим, что обращение:

Dispose(BookList, Done);

Вызывает автоматическое обращение к методу TBook.Done перед уничтожением каждого элемента коллекции, после чего уничтожается экземпляр TCollection. Это стало возможным потому, что объект TBooh объявлен нами как потомок от TObject. Если бы мы его объявили независимым объектом:

type
TBook = object
…..
end;

Мы должны были бы сами позаботиться об освобождении кучи, а обращение:

Dispose(BookList, Done);

Привело бы к "зависанию" программы.

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.