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

5 Вызов исключительной ситуации

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

raise ESampleError.Create('Error!');

После зарезервированного слова raise следует код, аналогичный тому, что используется для создания нового экземпляра класса. Действительно, в момент вызова исключительной ситуации создается экземпляр указанного класса; данный экземпляр существует до момента окончания обработки исключительной ситуации и затем автоматически уничтожается. Вся информация, которую нужно сообщить в обработчик ошибки, передается в объект через его конструктор в момент создания.

Почти все существующие классы исключительных ситуаций являются наследниками базового класса Exception и не содержат новых свойств или методов. Класс Exception имеет несколько конструкторов, какой из них конкретно использовать - зависит от задачи. Описание класса Exception можно найти в on-line Help.

6 Доступ к экземпляру объекта exception

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

Как уже говорилось, при вызове исключительной ситуации (raise) автоматически создается экземпляр соответствующего класса, который и содержит информацию об ошибке. Весь вопрос в том, как в обработчике данной ситуации получить доступ к этому объекту.

Рассмотрим модифицированную процедуру A в нашем примере:

procedure NewA;

begin

writeln('Enter A');

try

writeln('Enter A''s try block');

B;

writeln('After B call');

except

on ESE: ESampleError do writeln(ESE.Message);

on ESomethingElse do

writeln('Inside A''s ESomethingElse handler');

end;

writeln('Exit A');

end;

Здесь все изменения внесены в строку

on ESE: ESampleError do writeln(ESE.Message);

Пример демонстрирует еще одно новшество в языке Delphi - создание локальной переменной. В нашем примере локальной переменной является ESE - это тот самый экземпляр класса ESampleError, который был создан в процедуре C в момент вызова исключительного состояния. Переменная ESE доступна только внутри блока do. Свойство Message объекта ESE содержит сообщение, которое было передано в конструктор Create в процедуре C.

Есть еще один способ доступа к экземпляру exception - использовать функцию ExceptionObject:

on ESampleError do

writeln(ESampleError(ExceptionObject).Message);

7 Процедура Assert

Назначение специализированной процедуры Assert, - помощь в отладке кода и контроле над выполнением программы. Процедура является аналогом

макроса ASSERT, который широко применяется практически во всех программах, написанных с использованием C и C++ и их библиотек.

Синтаксис процедуры Assert:

procedure Assert(expr : Boolean [; const msg: string]);

Процедура проверяет логическое утверждение, передаваемое первым аргументом и, если

это утверждение ложно, то процедура выводит на экран диагностическое сообщение с номером

строки и именем модуля, где расположен вызов этой процедуры, и сообщение пользователя,

которое опционально передается вторым аргументом. Затем Assert принудительно завершает выполнение программы после выдачи соответствующего диагностического сообщения.

Процедура Assert обычно применяется в следующих случаях:

  • в начале процедуры или функции для проверки правильности переданных аргументов;

  • в конце работы алгоритма для проверки правильности работы алгоритма;

  • для проверки правильности выполнения "надежных" функций, то есть тех функций, которые всегда должны выполняться успешно всегда, и их невыполнение рассматривается как фатальная ошибка программы.

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

Директива компилятора $ASSERTIONS ON/OFF позволяет отключить генерацию кода процедуры Assert. Это обычно делается в уже отлаженных, годовых к использованию программах. Пример применения процедуры Assert:

program ShowAsserts;

{$APPTYPE CONSOLE}

uses SysUtils;

{$ENDIF}

type

TStorage = class(TObject)

FData: string;

property Data: string read FData write FData;

end;

procedure ModifyStorage(AStorage: TStorage; const s: string);

begin

Assert(AStorage <> nil, '');

AStorage.Data := s;

end;

var

Storage: TStorage;

begin

Storage := TStorage.Create;

try

ModifyStorage(Storage, 'Hello world');

finally

Storage.Free;

end;

// The following call is buggy and triggers the Assert

ModifyStorage(nil, 'Ooops');

end.