Стандартные процедуры 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.