Динамические объекты
ДИНАМИЧЕСКИЕ ОБЪЕКТЫ
Объектные переменные вo многом подобны обычным переменным Турбо
Паскаля, в частности, их можно размещать в динамической памяти. Турбо Паскаль
содержит средства, облегчающие размещение объектных переменных в куче и их
удаление из нее, например:
var
Pline:
^Tline;
.......
New(Pline, Init):
.......
В этом примере размещение объектной переменной (на нее
указывает PLINE) в куче сопровождается одновременным обращением к конструктору
TLINE.INIT для инициализации объекта и связывания виртуальных методов с вновь
созданной переменной: в процедуре NEW допускается в качестве второго параметра
указывать обращение к конструктору.
Более того, процедуру NEW можно вызывать и как функцию - в этом случае
она возвращает значение типа POINTER, указывающее на динамически распределенный
объект:
PLine := New(TLine);
или
PLine := New(TLine, Init):
Обратите внимание: первым параметром процедуре New
передается указатель на динамически распределяемый объект, в то время как
первым параметром функции NEW - тип распределяемого объекта. И в том, и в
другом случае в качестве втором параметра обращения допускается использовать
вызов конструктора, однако имя конструктора не может быть составным -ведь в
момент обращения динамический объект еще не создан. Например, оператор
New(Pline, PLine^.Init);
вызовет сообщение
об ошибке.
При обращении к NEW с одновременным вызовом конструктора
динамическая память резервируемая с помощью специального программного кода,
входящего в любой конструктор и вызываемого до начала работы исполняемой части
конструктора (до begin). При этом динамическая память может оказаться
исчерпанной. В этом случае стандартная функция обработки ошибок администратора
кучи выдает значение 0, что вызывает аварийное завершение программы с кодом
ошибки 203. Если используется нестандартная функция обработки ошибок и эта
функция возвращает 1, конструктор пропускает операторы после begin и возвращает
NIL. Таким образом гарантируется, что исполняемые операторы конструктора будут
работать только при условии нормального распределения динамической памяти.
Однако в теле конструктора может быть создан новый динамический объект, в нем -
свой и т.д. Турбо Паскаль
допускает
произвольную глубину вложенности конструкторов. Если на каком-то уровне
обнаружится нехватка динамической памяти, необходимо ликвидировать всю цепочку
успешно распределенных объектов. Чтобы эта операция стала возможной, в Турбо
Паскаль введена стандартная процедура без параметров FAIL, которая может
вызываться только из конструктора и которая освобождает уже выделенную
конструктором память, завершает его работу и возвращает NIL.
Для удаления динамического объекта из кучи используется
особый метод - деструктор, описываемый с помощью зарезервированного слова
DESTRUCTOR. В этом методе можно предусмотреть все действия, связанные с
ликвидацией динамического объекта (т.е. переменной объектного типа, размещенной
в динамической памяти), например, осуществить нужную коррекцию списка
динамических объектов. Обращение к деструктору указывается вторым параметром
при вызове процедуры DISPOSE, например:
..........
type
......
Constructor
Init;
Destructor
Done;
end;
.......
New(PLine,
Init); {Размещение динамического объекта}
.......
Dispose(PLine,
Done); {Удаление динамического объекта}
.......
При необходимости деструктор, как и любой другой метод
объекта
(кроме
конструктора!), можно объявить виртуальным.