Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Прикладное программирование.doc
Скачиваний:
8
Добавлен:
25.12.2018
Размер:
683.01 Кб
Скачать

Inherited Create;

FTitle:=AnTitle;

FFilm:=TFilm.Create; // FFilm: =Nil; если объект пока не нужен End;

Примечания:

Реализация метода начинается с указания зарезервированного слова Procedure\Function, за которым следует полное имя метода и параметры:

<имя класса>.<имя метода>[(<параметры>)];

Для метода-функции следует указать и <тип результатам.

Следует убедиться, что для каждого поля в конструкторе преду­смотрен оператор присвоения, и что все поля переходят из неопределенного состояния в какое-то конкретное, предусмотренное по умолчанию, хотя и известно, что транслятор сам выполнит инициализацию нулевыми значе­ниями ('', Nil, False - для других полей). Для неклассовых полей такая инициа­лизация вполне допустима, поскольку позволяет их использовать в дальней­шем. Инициализация классового поля значением Nil не позволяет непосред­ственное использование такого поля, поскольку память для хранения данных не отведена. При попытке обращения к такому полю будет выведено сооб­щение примерно следующего вида:

Для вызова наследуемого конструктора следует использовать клю­чевое слово Inherited, которое фактически обеспечивает доступность пере­крытого метода. Сила оператора в том, что он вызывает старое, а затем возвращается к новому.

Как правило, следует вызывать подходящий наследуемый конструк­тор в первом исполняемом операторе.

Только, если у пользовательского класса нет новых полей, можно не создавать для него конструктор.

В тех случаях, когда по каким-либо причинам не удается инициализи­ровать экземпляр класса полностью, должен быть предусмотрен механизм прекращения создания объекта и возврата к коду, вызвавшему конструктор, проинформировав его об ошибке и установив ссылку на объект в Nil. Ранее для этих целей была предусмотрена предопределенная процедура Fail. Она может использоваться сейчас, но только внутри конструкторов. Однако более прогрессивным считается использование механизма исключений, но о нем позже.

Хотя в объявлениях конструкторов и не указывается тип возвращае­мого результата, и они выглядят, как объявления процедур, конструкторы используются скорее как функции, а не как процедуры. Можно сказать, что конструктор является неявной функцией - он возвращает нового предста­вителя того класса, который использовался при его вызове. Нет необходи­мости в явном виде задавать тип возвращаемого результата, поскольку этот тип и так известен на момент вызова - это тип использованного в вызове конструктора класса.

Внутри конструктора отсутствует и явное присвоение возвращае­мого значения. Такое возможно, поскольку он всегда возвращает ссылку (адрес) на вновь созданный и инициализированный экземпляр класса.

Начиная с класса TComponent конструктор Create стал виртуальным и при его переопределении необходимо указывать слово-директиву Override, назначение которого будет пояснено позднее.

т) Реализация деструкторов.

Деструктор уничтожает экземпляр класса, который был использован при его вызове, автоматически освобождая любую динамическую память, которая ранее была зарезервирована конструктором, закрывает файлы и т.п. опера­ции. Деструктор вызывается тогда, когда работа с данным экземпляром клас­са закончена.

Как и в случае с конструктором нет необходимости заботиться о деталях освобождения динамической памяти уничтожаемого объекта, поскольку это делается автоматически. Программист ответственен за вызов деструкторов для всех экземпляров класса, если были зарезервированы подчиненные объ­екты.

Синтаксис реализации деструктора:

Destructor <имя класса>.<имя деструктора>[(<параметры>)];

[<блок объявлений>]

Begin

<исполняемые операторы>

End;

Реализация наследуемых деструкторов.

Если использовать механизм наследования деструкторов, то можно уп­ростить задачу уничтожения экземпляров класса, таким образом, чтобы каж­дый раз заботиться лишь об уничтожении тех полей, которые были добавле­ны в данном классе. Всю работу по очистке наследуемых полей можно воз­ложить на наследуемые деструкторы. Для вызова наследуемого деструктора необходимо используется ключевое слово Inherited. Синтаксис объявления наследуемого деструктора следующий:

Destructor <имя класса>.<имя деструктора>[(<параметры>)};

[<блок объявлений>]

Begin

<уничтожение собственных полей>

Inherited <имя деструктора>[{<параметры>)];

End;

Destructor TPictureShow-Destroy;

Begin

FFilm.Destroy; // Для полей-ссылок win FFilm.Free;

FTitle:="; // Для обычных полей

Inherited Destroy; // Можно вызвать и наследуемый TObject.Destroy

End;

Примечания:

Реализация деструктора начинается с указания зарезервированного

слова Destructor, за которым следует полное имя деструктора:

<имя класса>.<имя деструктора>.

Внутри деструктора есть доступ не только к обычным идентифи­каторам, но и к полям экземпляра класса, инкапсулированным при его опре­делении.

Исполняемые операторы деструктора должны позаботиться обо всех операциях очистки, необходимых для уничтожения экземпляра класса. Код деструктора должен уничтожить все внутренние экземпляры объек­тов и освободить динамическую память, которая была зарезервирована во время существования экземпляра класса. Однако нет необходимости явно устанавливать в нулевые значения поля прямого доступа.

Следует иметь в виду, что при неудачных попытках создания экземп­ляров класса деструктор, особенно Destroy, используемый по умолчанию, может быть вызван лишь с частично инициализированным экземпляром, по­этому он должен быть подготовлен к работе с полями, которые еще не

инициализированы.

Необходимость в объявлении деструкторов с параметрами возникает очень редко. Обычно все, что нужно сделать деструктору - уничтожить экземпляр класса, и вся необходимая для этого информация и так доступна ему.

Если у класса нет полей косвенного доступа, то деструктор можно не создавать для такого пользовательского класса.

Фактически нет не наследуемых конструкторов и деструкторов.

е) Вызов конструкторов.

Для того чтобы вызвать конструктор, необходимо правильно объявить и определить класс. Объявление класса должно быть доступно, т.е. он должен находится в области видимости из того места, где конструктор будет вызы­ваться.

Если в пользовательском классе не определен конструктор, то по умол­чанию будет использоваться конструктор, унаследованный от класса-потомка. В любом случае у всех объектов есть доступ к конструктору Create, определенному в классе TObject.

Определение класса создает активную структуру, способную создавать представителей этого класса. Объекты, которые создаются с помощью опре­деления класса, способны хранить ссылки на вновь создаваемые объекты.

Синтаксис объявления переменной и вызова конструктора следующий:

Var <имя обьекта>: <имя класса>; // Объявление переменной -указателя

Begin

. . .

<имя обьекта>:=<имя класса>.<имя конструктора>[(<параметры>)];

. . .

End;