Руководство по языку B.Pascal 7

       

Динамические переменные объектного типа


Стандартные процедуры New и Dispose допускают в качестве второго параметра вызов конструктора или деструктора для выделе- ния для памяти переменной объектного типа или ее освобождения. При этом используется следующий синтаксис:

New(P, Construct) и Dispose(P, Destruct)

где P - это указатель на переменную, ссылающийся на объектный тип, а Construct и Destruct - это вызовы конструкторов и деструк- торов объектного типа. Для New эффект расширенного синтаксиса тот же, что и от выполнения операторов:

New(P); P^.Construct;

а для Dispose это эквивалентно операторам:

P^.Dispose; Dispose(P);

Без расширенного синтаксиса вам пришлось бы часто вслед за вызовом конструктора вызывать New, или после вызова деструктора вызывать Dispose. Расширенный синтаксис улучшает читаемость ис- ходного кода и генерирует более короткий и эффективный код.

Приведенный пример иллюстрирует использование расширенного синтаксиса New и Dispose:

var SP: PStrField ZP: PZipField begin New(SP, Init(1, 1, 25, 'Имя')); New(ZP, Init(1, 2, 5, 'Почтовый индекс'), 0, 99999)); SP^.Edit; ZP^.Edit; . . . Dispose(ZP, Done); Dispose(SP, Done); end;

Вы можете также использовать New как функцию, распределяющую и возвращающую динамическую переменную заданного размера:

New(T) или New(T, Construct)

В первой форме T может быть любым ссылочным типом. Во второй форме T должен указывать на объектный тип, а Construct должен быть вызовом конструктора этого объекта. В обоих случаях типом результата функции будет T.

Приведем пример:

var F1, F2: PField begin F1 := New(PStrField, Init(1, 1, 25, 'Имя')); F1 := New(PZipField, Init(1, 2, 5, 'Почтовый индекс', 0,

99999)); . . . WriteLn(F1^.GetStr); { вызывает TStrField.GetStr } WriteLn(F2^.GetStr); { вызывает TZipField.GetStr } . . . Dispose(F2, Done); { вызывает TField.Done } Dispose(F1, Done); { вызывает TStrField.Done } end;

Заметим, что хотя F1 и F2 имеют тип PField, правила совмес- тимости по присваиванию расширенного указателя позволяют присваи- вать F1 и F2 указателю на любой потомок TField. Поскольку GetStr и Done являются виртуальными методами, механизм диспетчеризации виртуального метода корректно вызывает, соответственно, TStrString.GetStr, TZipField.GetStr, TField.Done и TStrField.Done.



Содержание раздела