Динамические объекты (Турбо Паскаль)

ДИНАМИЧЕСКИЕ ОБЪЕКТЫ
      Объектные переменные в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
           TLine = object(Point)
           ......
           Constructor Init;
           Destructor Done;
         end;
         .......
         New(PLine, Init);            {Размещение динамического объекта}
         .......
         Dispose(PLine, Done);   {Удаление динамического объекта}
         .......
      При необходимости деструктор, как и любой другой метод объекта
(кроме конструктора!), можно объявить виртуальным.