Файл: 13. Исключения и их объектная обработка.pdf

Добавлен: 20.10.2018

Просмотров: 639

Скачиваний: 9

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
background image

 

 

   try    // защищена  операция  

      { A[i] = A[i] / B[i]; }   

 catch (DivideByZeroException) 

   { Console.WriteLine(“Делитель = 0”); 

    } 

  . . . . . . . . . . // следующие операторы 

    try  // защищена операция 

        A[i] := A[i] / B[i]; 

    except   on   EDivByZero   do 

        ShowMessage(„Делитель = 0‟) 

end

   . . . . . . . . . // следующие операторы

 

 

Довольно  часто  в  программах  встречаются  расположенные  рядом 

опасные  операторы  разных  типов.  Защищать  блоком  try  каждый  из  них  в 

отдельности  достаточно  громоздко.  В  этом  случае  можно  оформить  один  

try-блок  сразу  на  группу  операторов,  а  в  блоке  обработки  предусмотреть 

возможность  реагирования  на  исключения  различных  типов.  Блок 

обработки в этом случае оформляется следующим образом:  

catch  (ИмяКласса1)  

    { обработка исключения типа 1} 

catch  (ИмяКласса2)  

    { обработка исключения типа 2} 

catch  (ИмяКласса3)  

    { обработка исключения типа 3 } 

. . . . . . . . . 

except    

   on   ИмяКласса1   do   обработка1; 

   on   ИмяКласса2   do   обработка2; 

   on   ИмяКласса3   do   обработка3; 

. . . . . . . .  

end;

 

 

В  этом  случае  важным  является  порядок  следования  обработчиков: 

сначала  указываются  обработчики  наиболее  конкретных  типов,  а  потом  -  

более общих типов.  Это связано с тем, что при возникновении исключения 

поиск  подходящего  обработчика  выполняется  по  порядку  их  следования  в 

блоке  и  в  соответствии  с  иерархической  принадлежностью.  Как  только 

будет найден первый подходящий обработчик, он выполняется а остальные 

просто пропускаются.  

Вот пример правильной организации списка обработчиков: 

catch  (DivideByZeroException)  

except    


background image

 

 

    {обработка ошибки деления на 0} 

catch  (

ArithmeticException

 )  

    {обработка других арифм. ошибок} 

catch  (Exception )  

    { обработка всех остальных 

ошибок любого типа (корень!)} 

 

   on   EDivByZero   do   . . . . . 

// обработка ошибки деления на 0 

   on   EIntError   do  . . . . . 

// обработка других арифм. ошибок 

   on   Exception   do   . . . . . 

// обработка всех остальных ошибок 

end;

 

 

Если  в  защищенном  коде  возникает  ошибка,  обработчик  которой  не 

предусмотрен  в  блоке  catch/except,  то  автоматически  вызывается 

стандартный системный обработчик, который выводит общее сообщение и 

аварийно завершает работу.  

Наиболее  полный  анализ  возникшей  особой  ситуации  предоставляет 

автоматически 

создаваемый 

объект-экземпляр 

некоторого 

класса 

исключения.  Для  получения  доступа  к  этому  объекту  надо  просто  вместе  с 

именем класса объявить еще и имя объектной переменной: 

catch  (ИмяКласса   ИмяОбъекта)  

      { обработка с использованием переменной   ИмяОбъекта } 

except   on   (ИмяОбъекта : ИмяКласса)   do   

      //  обработка с использованием переменной   ИмяОбъекта 

  

Иногда  возникает  необходимость  программно  сгенерировать  некоторое 

исключение. Для этого можно использовать специальные операторы: 

  в языках  Java, C#  и  C++  оператор  throw 

  в  Delphi  -  оператор   raise 

Синтаксически  использование  этих  операторов  похоже  на  создание 

объектов, что, впрочем, и происходит на самом деле: надо указать имя класса 

исключений и один из его конструкторов: 

  throw   new   ИмяКласса (параметры конструктора) 

  raise   ИмяКласса.Create (параметры) 


background image

 

 

Хотя  стандартных  типов  исключений  достаточно  для  подавляющего 

числа  практических  ситуаций,  при  необходимости  можно  создать  и 

собственные  нестандартные  исключения.  Для  этого  достаточно  создать 

новый  класс  как  производный  от  базового  класса    Exception,  используя 

стандартный синтаксис объявления дочернего класса.    

В  завершение  данного  раздела  отметим  еще  одну  полезную 

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

try/catch    или      try/except      можно  использовать  конструкцию  типа  

try/finally.      Она  позволяет  оформить  так  называемый  блок  завершения

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

возникновения  исключения.  Блок  завершения  целесообразно  использовать 

для освобождения занятых ресурсов, например – освобождение динамически 

выделенной  памяти,  закрытие  файлов  и  т.д.  Очень  часто  блоки  обработки 

исключений и завершения объединяются вместе в одну конструкцию, причем 

сначала оформляется блок обработки, а затем – блок завершения. 

try   { 

. . . . . . .   } 

catch ( . . . . . ) { . . . . .  } 

catch ( . . . . . ) { . . . . .  } 

catch ( . . . . . ) { . . . . .  } 

finally   { код завершения } 

 

try 

. . . . . . .  

except 

on  . . . .   do   . . . . . 

on  . . . .   do   . . . . . 

finally   //  код завершения 

end;