Динамическими могут быть объекты со статическими и виртуальными методами. Удаление динамических объектов может быть с помощью процедур Dispose или с помощью деструктора.
Подобно другим динамическим типам данных динамические объекты со статическими методами могут удаляться с помощью Dispose. Например:
Dispose ( P1 );.
Пример программы с динамическим объектом со статическими методами дан в листинге 5.
Листинг 5.Динамические объекты со статическими методами.
Program novirt; Uses Crt; { Объявления: }
Type ObjName1 = object { - объекта-предка }
Fl1 : integer;
Procedure Met1;
Procedure Met2; End;
ObjName2 = object ( ObjName1 ) { - объекта-потомка }
Procedure Met2; End;
PobjName1 = ^ObjName1; {-тип - указатель на объект ObjName1 }
PObjName2 = ^ObjName2; { - " " " " ObjName2 }
{ -- Методы объекта ObjName1 ------- }
Procedure ObjName1.Met1; Begin
Met2; { - вызов только метода ObjName1.Met2 !!}
End;
Procedure ObjName1.Met2; Begin FL1 := 12;
Writeln ( 'Работает метод ObjName1.Met2: Fl1 = ', FL1) End;
{ -- Методы объекта ObjName2 ------ }
Procedure ObjName2.Met2; Begin FL1 := 34;
Writeln ( 'Работает метод ObjName2.Met2: Fl1 = ', FL1) End;
Var V1 : PobjName1; { - динамический объект V1 } V2 : PObjName2; { - " " V2 }
{ ------ Основная программа----------- }
Begin ClrScr;
Assign (Output, 'dnovirt.res'); Rewrite (output);
Writeln ('ДИНАМИЧЕСКИЕ ОБЪЕКТЫ, СТАТИЧЕСКИЕ МЕТОДЫ'); Writeln ('Работаем с VI - экземпляром типа предка');
New ( V1 ); { - создание динамического объекта V1 }
V1^.Met1; { - вызов метода ObjName1 .Met1; }
Vl1.Met2; { - " " ObjName1.Met2; }
Dispose ( V1 ); { - удаление объекта V1 }
Writeln ('Работаем с V2 - экземпляром типа потомка');
New ( V2 ); { - создание динамического объекта V2 }
V2^.Met1; { - вызывает ВСЕГДА метод ObjName1.Met2,
а не ObjName2.Met2 }
V2^.Met2; { - вызов метода ObjName2.Met2; }
Dispose ( V2 ); { - удаление объекта V2 }
Close (Output);
End.
Для освобождения ОП динамических объектов с виртуальными методами используются особые методы - деструкторы. В качестве их имен рекомендуется употреблять имя Done. Они предназначены для выполнения завершающих действий программы. Деструктор размещается вместе с другими методами объекта в определении типа и оформляется так же, как обычный метод-процедура, но слово PROCEDURE заменяется словом DESTRUCTOR. Например: Destructor TObjl.Done;.
Вызов деструктора (Done) вне процедуры Dispose не приведет к автоматическому освобождению ОП, занимаемой экземпляром объекта, т. е. недопустимо Р1^.Done;.
Для корректного освобождения ОП, которую реально занимает экземпляр динамического объекта с поздним связыванием, деструктор надо вызывать с помощью расширенного типа процедуры Dispose. Он имеет 2 параметра: имя указателя на объект и имя деструктора. Например:
Dispose ( PI,Done);
где Done - имя деструктора объекта, на который указывает Р1.
Деструктор выполняется как обычный метод. Когда будет выполнено последнее его действие, если объект содержит виртуальные методы, то деструктор производит поиск размера объекта в ТВМ и передает его процедуре Dispose, которая и освобождает правильное количество байт, независимо от того, указывал ли Р1 на тип предка или потомка.
Метод деструктора может быть и пустым, так как основная информация содержится не в теле деструктора, а связана с его заголовком, содержащим слово Destructor.
Деструктор потомка последним своим действием должен вызывать соответствующий деструктор своего непосредственного предка, чтобы освободить ОП всех наследуемых указателей объекта. Например:
Destructor Tobj1.Done;