Начальные значения свойств объекта, как и у любых других переменных в Паскале, являются неопределенными. Поэтому следующий фрагмент кода в корне неверен!
TYPE TA=CLASS
a:WORD;
PROCEDURE Sum;
END;
…
PROCEDURE TA.Sum;
BEGIN
a:=a+1
END;
…
VAR x:TA;
BEGIN
x.Sum;
Здесь вызывается метод Sum объекта ТА, в котором значение свойства а увеличивается на единицу. Проблема в том, что начальное значение свойства а не задано и такая операция не имеет смысла – в а может оказаться любое произвольное значение.
Очевидный выход – явная инициализация всех свойств. В рассматриваемом примере можно было бы написать:
VAR x:TA;
BEGIN
х.a:=0.0;
x.Sum;
Но такая запись не только некрасива, но и чревата ошибками: рано или поздно программист забудет проинициализировать одно из свойств.
Хуже того: так как объекты хранятся в динамической памяти, под наш объект вообще не будет выделено памяти – мы же не попросили об этом компилятор! Поэтому вышеприведенный фрагмент программы на строчке х.a:=0.0; "свалится", выдав кучу страшных сообщений.
Для разрешения этих трудностей в Паскале введен особый вариант метода объекта, называемый конструктором (constructor). Он выполняется один раз перед первым использованием объекта (иначе говоря, при его создании). Конструктор – это обычная процедура, только вместо PROCEDURE пишется CONSTRUCTOR. Как и другие методы, заголовок конструктора описывается при задании объектного типа данных:
TYPE TA=CLASS
a:WORD;
CONSTRUCTOR Create;
PROCEDURE Sum
END;
CONSTRUCTOR TA.Create;
BEGIN
a:=0
END;
Конструктор выполняет две главные функции (рис. 5.1): инициализацию объекта (выделение памяти под него) и задание начальных свойств методов или, что то же самое, задание начального состояния моделируемого объекта.
Рис. 9.1. Функции конструктора.
В Delphi каждый объект обязан иметь конструктор, который называется Create. Попытка работать с объектом, для которого не выполнялся метод Create, приводит к ошибке. Как правило, метод Create вызывается при создании переменной объектного типа:
VAR x:TA;
BEGIN
x:=TA.Create;
Если уж у нас есть особый метод, выполняемый при рождении объекта, логично предположить, что должен быть и метод, выполняемый при его кончине. Разумеется, он называется деструктор (destructor). Главная задача деструктора – освобождение динамической памяти, выделенной в конструкторе. Если этого не сделать, то произойдет самое страшное программистское преступление – утечка памяти. Мы подробнее рассмотрим этот вопрос в главах, посвященных работе с динамической памятью. Традиционным именем деструктора в Delphi является Free.