Реферат Курсовая Конспект
Обработка исключительных ситуаций. - раздел Программирование, Объектно-ориентированное программирование Во Время Работы Программы Часто Встречаются Исключительные Ситуации: Деление ...
|
Во время работы программы часто встречаются исключительные ситуации: деление на 0, отсутствие места на диске или попытка писать на защищенную для записи дискету, ошибочный символ при вводе (например, буква вместо цифры). В современных языках программирования для таких случаев предусмотрены специальные средства — обработчики исключительных ситуаций. В Delphi имеются 2 типа так называемых защищенных блоков кода:
1)try...finally...end;
2)try...except...end;
1) try...finally...end: если исключительных ситуаций не было, операторы в блоке try выполняются в обычном порядке, после чего выполняются операторы в блоке после finally. Если же возникла исключительная ситуация в блоке "try", выполнение блока прерывается, и сразу выполняется блок "finally" (его обычно используют для высвобождения ресурсов, и поэтому часто называют блоком "очистки кода"). Специальных операторов для этого типа обработки нет. Отличие кода внутри блока finally...end от кода, стоящего после этого end, возникает только при наличии внутри блока try операторов break или exit, т.к. в этом случае независимо от их срабатывания или несрабатывания сначала происходит выполнение блока очистки кода.
2) try...except...end: если исключений не было, выполняется только блок try. Если же возникла исключительная ситуация в блоке try, то обычная последовательность прекращается, и управление для обработки этой операции сразу передается в блок "except" со специальным синтаксисом:
try
...
except
on MyException1 do...{оператор1};
on MyException2 do...{оператор2}; ...
else {обычно отсутствует; не рекомендуется использовать}
MyOtherException {оператор обработки остальных исключений}
end{/except};
Исключительные ситуации являются классами-потомками объектного типа Exception=class(tObject) из модуля SysUtils и либо предопределены в системе (существуют исключительные ситуации: ZeroDivBy для операций с "плавающей запятой", DivByZero для целочисленных операций, InvalidGraphic и т.д.), либо описываются пользователем как потомки Exception (или его потомков).
Если ошибки не было, блок except не выполняется. Если ошибка была, выполняется блок except, после чего управление обратно в try не передается. При этом ищется первое соответствие исключения обработчику. Так, если возникла исключительная ситуация типа MyException1 (предопределенная или определенная в программе), то после выполнения оператора1 будет произведен выход из блока try...except...end без проверки на соответствие другим типам исключений.
По правилу совместимости типов исключительная ситуация типа-потомка всегда может быть обработана как исключение прародительского типа. Поэтому порядок следования обработчиков в блоке except имеет большое значение: обработчик исключения более общего типа следует писать всегда после обработчика для его типа-потомка ,иначе обработчик потомка никогда не будет вызван.
Пример обработки исключений:
procedure MyETest(var X,Y,Z:real);
begin
try
Z:=sqrt(X/Y);
except
on EZeroDivide do messageBox('Деление на ноль',’Y’,mb_Ok);
on EInvalidOp do messageBox('Корень из отрицательного числа!',
‘Y’,mb_Ok);
end{/except};
end;
Если бы мы поставили строку EInvalidOp перед EZeroDivide..., то при делении на нуль обработчик для EInvalidOp перехватывал бы управление, и обработчик для EZeroDivide никогда бы не срабатывал.
Во время обработки исключительной ситуации некого типа создается объект-исключение соответствующего типа. Обычно имени типа исключения бывает достаточно, и объект-исключение остается без имени. Но при необходимости исключение может быть поименовано в блоке on..do, если в блоке do нужен доступ к полям объекта:
...
on EZD:EZeroDivide do EZD.message:='Деление на ноль. Проверьте
данные';
Таким образом, можно не только заменять, но и переопределять стандартные обработчики исключений. Например, в файле проекта (расширение .dpr — сокращение от Delphi project) можно сделать следующую обработку исключений:
try {создание формы}
application.CreateForm(tForm1,Form1);
application.Run;
except
on E:Exception do
begin messageBox(E.message,’Y’,mb_Ok);
E.message:='Ошибка в программе';
Raise;
end{/do};
end{/except};
Замечание: исключения, в отличие от других типов, принято именовать с буквы "E", а не с "t".
Некоторые важнейшие типы исключений:
· EMathError — все математические ошибки;
· EInOutError — все ошибки ввода-вывода;
· EConvertError — ошибки преобразования типов;
· EOutOfMemory — нехватка памяти;
· EPrinter — ошибка работы с принтером;
· EAbort — вызывается программно вызовом процедуры Abort; не делает ничего и предназначена для обработки программистом для нужд текущей программы.
Блоки защиты ресурсов и обработчики исключительных ситуаций могут быть вложенными. Например, выделение ресурсов можно производить так:
try {1}
allocateResource1;
try {2}
allocateResource2;
UseResources;
finally{2}
FreeResource2;
end{/try2};
finally{1}
FreeResource1;
end{/try1};
Другой вариант решения этой проблемы:
const Ok1,Ok2:Boolean:=False;
...
try
AllocateResource1;
Ok1:=True;
AllocateResource2;
Ok2:=True;
except
on Exception do
begin
if Ok2 then
begin
FreeResource2;
if Ok1 then FreeResource1;
end{/if};
end{/do};
end{/except};
Можно вкладывать друг в друга обработчики исключений:
procedure ECheck(var A,B,Y,Z:Real);
var X:Real;
begin
try{1}
X:=(-B*X+sqrt(B*B-4*A*C))/(2*A);
try{2}
Z:=X/sqrt(A*Y*Y-7*B/A/(X-3sqrt(B)));
except{2}
on EMathError do
application.MessageBox('ошибка в вычислении Z',Y,mb_Ok);
end{/except2};
except{1}
on EMathError do
application.MessageBox('ошибка в вычислении корня
уравнения ',Y,mb_Ok);
end{/except1};
end{/ECheck};
Для создания собственной исключительной ситуации в случае, когда обычные исключения не возбуждаются, надо описать соответствующий класс, например:
EWrongPassword=
class(Exception)
end;
В теле класса можно ничего не описывать! В реализации программы в нужный момент надо инициализировать исключение с помощью конструктора, и тогда обработчик исключений сможет его обработать.
Например:
var S,S1:String;
try
S:=...
...
myReadPassword(S1);
if(S1<>S)then EWrongPassword.Create('Wrong password!');
...
except
on EWrongPassword do...;
end{/except};
...
Создание и обработка исключительных ситуаций позволяют структурным способом решить проблемы, в которых в обычном PASCAL приходилось использовать метки и оператор goto, а также ставить огромное число проверок на допустимость присваиваний и математических операций. Мало того, что эти проверки резко замедляли работу программы — не было гарантии, что они достаточны, и что во время работы программы не возникнет "вылет" из-за возникновения непредусмотренной исключительной ситуации. В Object Pascal, как мы видим, эта проблема решена кардинально.
Замечание: в "С-образных" языках С++, JavaScript и Java также имеется обработка исключительных ситуаций, построенная по варианту try...catch..., аналогичная try...except... для Object Pascal (слово "catch" означает "перехватить"). Существенное отличие — после обработки одного исключения производится переход к следующему, если не поставить оператор break, такая логика работы очень часто приводит к ошибке, которую можно назвать "забытый break ".
– Конец работы –
Эта тема принадлежит разделу:
На сайте allrefs.net читайте: "Объектно-ориентированное программирование"
Если Вам нужно дополнительный материал на эту тему, или Вы не нашли то, что искали, рекомендуем воспользоваться поиском по нашей базе работ: Обработка исключительных ситуаций.
Если этот материал оказался полезным ля Вас, Вы можете сохранить его на свою страничку в социальных сетях:
Твитнуть |
Новости и инфо для студентов