Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ПЯВУ.docx
Скачиваний:
2
Добавлен:
23.04.2019
Размер:
210.36 Кб
Скачать

39. Решение проблемы утечки ресурсов с использованием механизма исключений.

Решение проблемы утечки ресурсов в блоке try ..finally. Основными недостатками стандартной обработки исключений являются недружественность пользовательского интерфейса, связанная с выводом неинформативных для пользователя сообщений на английском языке, и проблема утечки ресурсов. Для того чтобы избежать утечки ресурсов, можно использовать специальную конструкцию обработки исключения: try ...finally. Try «операторы, способные привести к исключению» finally «операторы, выполняемые в любом случае» end;

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

В разделе finally неудобно описывать реакцию на исключение, поскольку он не предоставляет механизма доступа к объекту исключения. Поэтому разделы except, и finally могут использоваться совместно.

Блок try...finally...end обладает еще одной важной особенностью. Если он помещен в цикл, то вызов из защищенного блока процедуры Break с целью преждевременного выхода из цикла или процедуры Continue с целью перехода на следующую итерацию цикла сначала обеспечивает выполнение секции finally...end, а затем уже выполняется соответствующий переход. Это утверждение справедливо также и для процедуры Exit (выход из подпрограммы). Рассмотренный выше блок try...finally позволяет защитить ресурсы внутри блока.

40.Базовый класс исключений Exception.Все предопределенные в Delphi классы исключений являются прямыми или косвенными наследниками класса Exception, объявленного в модуле SysUtils и наследующего непосредственно TObject.

В классе Exception объявлено два свойства:1)message тип sting-строка сообщения,которая отображается на окне при обработке искл системным обработчиком сообщений;

2)helpContext тип integer-целый инедфекатор экрана контексно-зависимой справки,отображаемого,при нажатии ф1 в окне с сообщением об ошибке. По умолчанию 0.

Класс Exception наследует все функции своего базового класса TObject, в частности, полезную для идентификации неизвестного исключения функцию ClassName.

В интерфейсе класса Exception описаны 8 конструкторов, наследуемых всеми исключениями:

1)create-конструктор передает строку сообщения Msg св-вуMessage;

2)createFmt-конструктор формирует строку св-ва Message,исходя из строки описания формата Msg и массива аргумента Args;

3)CreateRes-конструктор задает строку св-ва Message идентификатором Ident строки сообщения в ресурсах проекта;

4) CreateResFmt-конструктор задает строку св-ва Message идентификатором Ident строки сообщения в ресурсах проекта и массива аргумента Args;

5) CreateHelp-конструктор передает строку сообщения Msg св-вуMessage;передает св-ву HelpContext идентификатор HelpContext экрана контексной-зависимой справки по этому исключению;

6) CreateFmtHelp- конструктор формирует строку св-ва Message,исходя из строки описания формата Msg и массива аргумента Args; передает св-ву идентификатор HelpContext экрана контексной-зависимой справки по этому исключению;

7) CreateResHelp- конструктор задает строку св-ва Message идентификатором Ident строки сообщения в ресурсах проекта; передает св-ву идентификатор HelpContext экрана контексной-зависимой справки по этому исключению;

8) CreateRaFmtHelp- конструктор задает строку св-ва Message идентификатором Ident строки сообщения в ресурсах проекта и массива аргумента Args; передает св-ву идентификатор HelpContext экрана контексной-зависимой справки по этому исключению;

Пример вызова конструктора Create.

{Генерация собственного исключения EMyException}

Raise EMyException.Create (‘Не хватает исходных данных’);

{Генерация исключения EZeroDivide с измененным сообщением}

Raise EZeroDivide.Create (‘Деление на нуль’);

{Использование функции format}

Raise EMyException.Create (format (‘Задано %d параметров из %d’, [N1,N2]));

Пример вызова конструктора CreateFmt:

Raise EMy.CreateFmt (‘Задано %d параметров из %d’, [N1,N2]));

В отличие от конструктора Create конструкторы имеющие в своем названии Fmt, сами неявно обращаются к функции Format, так что запись конструктора несколько упрощается.

Пример вызова конструктора CreateHelp:

Raise EMy.CreateHelp (‘Не хватает исходных данных’, 10)

Пример вызова конструктора CreateResFmt при условии, что в файле ресурсов существует форматная строка с номером 65369, в которой требуется подстановка двух параметров тех же типов, что и переменные N1 и N2.

Raise EMy.CreateResFmt (65369, [N1,N2])

41. Преднамеренная генерация исключений. Создание собственного исключения. Преднамеренная генерация исключенийИскусственная генерация исключений используется, например, если, несмотря на то, что в текущем блоке произошла обработка какого-либо исключения, требуется передать его во внешний блок. В этом случае в обработчике надо сгенерировать исключение того же типа, что и прежнее, поскольку прежнее автоматически разрушается.Генерация исключения осуществляется ключевым словом raise. Общая схема такой двухэтапной обработки:

Try

<операторы внешнего блока>

Try

<операторы, способные привести к генерации исключения>

Except

On <тип исключения> do

Begin

<обработка исключений, сгенерированных во внутреннем блоке.>

Raise; {повторная генерация исключения}

End;

<операторы внешнего блока; при генерации исключения не выполняются>

Except

On ESomething do

<обработка исключений и внутреннего и внешнего блока>

End;

В этом примере, исключения, сгенерированные во внутреннем блоке, обрабатываются в два этапа: сначала обработчиком внутреннего блока, затем обработчиком внешнего блока. Операторы внешнего блока, следующие за внутренним, при генерации исключения во внутреннем блоке выполняться не будут. Исключения, сгенерированные во внешнем блоке, будут обрабатываться только обработчиками этого внешнего блока.

С помощью ключевого слова raise можно сгенерировать не только повторное исключение, но и исключение любого типа в любом месте программы.

Синтаксис оператора генерации исключения:

raise <Исключение>;

Вместо исключения можно указать тип исключения и один из его конструкторов. Например:

raise <тип исключения>.Create(<текст сообщения>)

Здесь <тип исключения> может быть любым из предопределенных в Delphi, а <текст сообщения> — тем текстом, который будет отображен в диалоговом окне стандартной обработке исключения. При этом тип исключения и текст сообщения могут никак не быть связаны друг с другом.

Можно использовать предопределенные в Delphi исключения для собственных целей, например, передачи информации об ошибках. Однако предпочтительней для этих целей создавать собственные классы исключений.

Создание собственного исключенияВсе классы исключений в Delphi являются наследниками класса Exception. Это означает, что все исключения содержат свойства и методы класса Exception, но могут также содержать дополнительную информацию, специфичную для конкретного исключения. Если никакой дополнительной информации не требуется, то объявление нового класса исключений производится в разделе tуре оператором вида:

type

<имя_класса_исключения> = сlass (Exception);

Например, для сообщения об отсутствии какой-то информации можно создать свой класс исключений с именем ENoInf.

Type ENoInf=class(Exception);

В различных местах программы перед выполнением каких-то действий с данными, заданными пользователем, можно проверять полноту информации и при необходимости генерировать исключение оператором вида:

Type ENoInf.Create(‘Не задана требуемая информация’)

Текст сообщения формируется при генерации исключения. Это исключение будет перехватываться системными средствами, и пользователю будет выводиться диалоговое окно сообщения об ошибке. Если же требуется конкретизация сообщения пользователю, то можно использовать блоки try...ехсерt., в которых генерировать соответствующие исключения и вставлять в раздел ехсерt их обработку.

Если необходимо создать класс исключений, содержащих дополнительные поля, определение такого класса должно иметь вид.

type

<имя класса Исключения>=class(Exception)

<Поля>

End;

Например, объявление:

EMy=class(Exception)

Enum: integer;

End;

создает класс исключения с именем EMy, имеющим открытое поле c именем Enum, в которое вы можете при генерации заносить, например, условный идентификатор, конкретизирующий причину исключения.