Конструкторы и деструкторы
Корректная работа с виртуальными методами требует определенных правил.
Если объектный тип содержит хотя бы один виртуальный метод, то он должен иметь хотя бы один особый метод, называемый конструктором(этот метод может быть и унаследован). Конструктор должен быть применен к экземпляру объекта до первого вызова виртуального метода так же, как перед обращением к динамической переменной необходимо ее создать. Кроме этого, каждый экземпляр объекта должен инициализироваться отдельным вызовом конструктора. Другие экземпляры, даже если они содержат правильные данные, но не проинициализированы, приведут к ошибке выполнения при любых вызовах их виртуальных методов. Например:
Var
OnePoint, TwoPoint: Point;
Begin
OnePoint.Create (50,100);
…
TwoPoint.Move (21, -20); { Неправильный вызов, второй экземпляр не создан }
Каждый тип объекта, содержащий виртуальные методы, имеет таблицу виртуальных методов (ТВМ), хранящуюся в области данных. ТВМ содержит размер типа объекта и для каждого виртуального метода указатель кода, исполняющий данный метод. Конструктор устанавливает связь между вызывающим его экземпляром объекта и его ТВМ.
Так как имеется только одна ТВМ для любого типа объекта, то отдельные экземпляры объекта содержат только адрес ТВМ, а конструктор устанавливает значение этого адреса.
С процедурой освобождения памяти связан особый вид метода, называемый деструктором, и предназначенный для выполнения действий завершающего характера. В отличие от методов-конструкторов, деструкторы могут быть виртуальными и могут наследоваться, в одном объектном типе может быть определено несколько деструкторов.
В случае единственного деструктора в Турбо Паскале рекомендуется использовать название Done. Этот метод должен инкапсулировать все детали очистки своего и вложенных объектов и структур данных. Основное преимущество использования деструктора заключается в удалении из памяти полиморфных объектов, то есть таких, которые были созданы во время вызова метода, а не во время компиляции.
Так как размеры типов объектов различны, то во время компиляции из полиморфного объекта нельзя извлечь какую-либо информацию о его размере. Эта информация становится доступной для деструктора в момент удаления при обращении к таблице виртуальных методов экземпляров объектов этого типа.
Сам по себе метод деструктора может быть пустым и выполнять только функцию связи с процедурой высвобождения памяти:
Destructor Point.Done;
Begin
End;
Деструктор дочернего типа последним действием должен вызывать соответствующий деструктор своего непосредственного предка, чтобы освободить поля всех наследуемых указателей объекта. В Турбо Паскале можно использовать служебное слово INHERITED (V7.0), с помощью которого можно вызывать методы предка без указания его имени, например:
Destructor Circle.Done;
Begin
INHERITED Done;
End;
Дата добавления: 2016-06-29; просмотров: 1362;