Файл: Pobegaylo_A._C_Cplus_dlya_studenta.pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 13.12.2020

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

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

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

Глава 13. Обработка исключений 

171 

В  листинге  13.4  приведена  программа,  в  которой  используется 
обработчик исключений любого типа. 

Листинг 13.4. Использование обработчика исключений  
любого типа 

#include <iostream> 
using namespace std; 
struct Zero {}; 
struct NonZero {}; 
int main() 

  int n; 
 
  try 
  { 
    cout << "Input integer: ";  // Введите целое число 
    cin >> n ; 
 
    if (n) 
      throw NonZero(); 
    throw Zero(); 
  } 
  catch(...) 
  { 
    cout << "Zero or NonZero exception" << endl; 
  } 
  cout << "OK" << endl; 
 
  return 0; 

13.4. Вложенные исключения 

В блок 

try

 могут быть вложены другие блоки 

try

 со своими об-

работчиками исключений. В этом случае обработчик исключения 
ищется  последовательно  от  самого  внутреннего  блока 

try

  к  са-

мому внешнему блоку 

try


background image

Часть II. Язык программирования С++ 

172 

В листинге 13.5 приведен пример программирования вложенных 
блоков 

try

Листинг 13.5. Программирование вложенных блоков 

try

 

#include <iostream> 
using namespace std; 
 
struct UnderZero {}; 
struct Zero {}; 
struct AboveZero {}; 
 
int main() 

  int n; 
 
  cout << "Input integer: "; 
  cin >> n; 
  try 
  { 
    if (n < 0) 
      throw UnderZero(); 
    try 
    { 
      if (n > 0) 
        throw AboveZero(); 
      throw Zero(); 
    } 
    catch(AboveZero) 
    { 
      cout << "AboveZero exception." << endl; 
    } 
  } 
  catch(UnderZero) 
  { 
    cout << "UnderZero exception." << endl; 
  } 
  catch(Zero) 
  { 
    cout << "Zero exception." << endl; 
  } 


background image

Глава 13. Обработка исключений 

173 

  cout << "OK" << endl; 
 
  return 0; 

Блок 

try

 с обработчиками исключений может быть вложен в блок 

catch

. В этом случае подходящий обработчик исключения ищется 

только внутри блока 

catch

, в который вложен блок 

try

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

throw

 без объекта. В этом случае новое 

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

Листинг 13.6. Передача управления по иерархии обработчиков  
исключений 

#include <iostream> 
using namespace std; 
struct FreeMemory {}; 
 
int main() 

  int* n; 
  int* m; 
 
  try 
  { 
    n = new int; 
    cout << "Input n: ";  // введите целое число 
    cin >> *n ; 

    try 
    { 
      m = new int; 


background image

Часть II. Язык программирования С++ 

174 

      cout << "Input m: ";  // введите целое число 
      cin >> *m ; 
 
      throw FreeMemory();   // нужно освободить память 
    } 
    catch(FreeMemory) 
    { 
      cout << "m = " << *m << endl; 
      delete m; 
      throw;  // нужно еще раз освободить память 
    } 
  } 
  catch(FreeMemory) 
  { 
    cout << "n = " << *n << endl; 
    delete n; 
  } 
 
  return 0; 

Отметим,  что  использование  инструкции 

throw

  без  выражения 

в блоке 

try

 приводит к завершению программы. 

13.5. Реализация исключений 

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

try

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


background image

Глава 13. Обработка исключений 

175 

При  удалении  локальных  объектов  из  стека  для  каждого  из  них 
вызывается деструктор. Такой процесс поиска нужного обработ-
чика исключения называется 

раскруткой стека

 (stack unwinding). 

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

13.6. Спецификация исключений 

Спецификацией  исключений

  называется  перечисление  в  объявле-

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

  throw(список_типов) 

Здесь 

список_типов

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

ний,  которые  может  выбросить  функция  при  своем  исполнении. 
Например, предполагается, что функция: 

  void foo(void) throw(char*, int); 

может выбросить только исключения типов 

char*

 и 

int

Если список типов исключений пуст, то это означает, что функ-
ция не выбрасывает никаких исключений. Например: 

  void foo(void) throw(); 

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


Смотрите также файлы