Опубликован: 26.06.2003 | Уровень: для всех | Доступ: платный
Лекция 16:

Обработка ошибок

< Лекция 15 || Лекция 16: 123 || Лекция 17 >

Исключительные ситуации

В языке Си++ реализован специальный механизм для сообщения об ошибках – механизм исключительных ситуаций. Название, конечно же, наводит на мысль, что данный механизм предназначен, прежде всего, для оповещения об исключительных ситуациях, о которых мы говорили чуть ранее. Однако механизм исключительных ситуаций может применяться и для обработки плановых ошибок.

Исключительная ситуация возникает при выполнении оператора throw. В качестве аргумента throw задается любое значение. Это может быть значение одного из встроенных типов (число, строка символов и т.п.) или объект любого определенного в программе класса.

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

Предположим, из main была вызвана функция foo, которая вызвала метод Open, а он в свою очередь возбудил исключительную ситуацию:

class Database
{
public :
    void Open(const char*serverName);
};
void
Database::Open(const char*serverName)
{
    if (connect(serverName)==false )
        throw 2;
}
foo()
{
    Database database;
    database.Open("db-server");
    String y;
    ...
}
int main()
{
    String x;
    foo();
    return 1;
}

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

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

Обработка исключительных ситуаций

В программе можно объявить блок, в котором мы будем отслеживать исключительные ситуации с помощью операторов try и catch:

try {
	...
}catch (тип_исключительной_операции){
	...
}

Если внутри блока try возникла исключительная ситуация, то она первым делом передается в оператор catch. Тип исключительной ситуации – это тип аргумента throw. Если тип исключительной ситуации совместим с типом аргумента catch, выполняется блок catch. Тип аргумента catch совместим, если он либо совпадает с типом ситуации, либо является одним из ее базовых типов. Если тип несовместим, то происходит описанный выше откат вызовов, до тех пор, пока либо не завершится программа, либо не встретится блок catch с подходящим типом аргумента.

В блоке catch происходит обработка исключительной ситуации.

foo()
{
  Database database;
  int attempCount =0;
again:
  try {
    database.Open("dbserver");
  } catch (int& x){
    cerr <<"Ошибка соединения номер "
                                 <<x <<endl;
    if (++attemptCount <5)
      goto again;
    throw ;
  }
  String y;
  ...
}

Ссылка на аргумент throw передается в блок catch. Этот блок гасит исключительную ситуацию. Во время обработки в блоке catch можно создать либо ту же самую исключительную ситуацию с помощью оператора throw без аргументов, либо другую, или же не создавать никакой. В последнем случае исключительная ситуация считается погашенной, и выполнение программы продолжается после блока catch.

С одним блоком try может быть связано несколько блоков catch с разными аргументами. В этом случае исключительная ситуация последовательно "примеряется" к каждому catch до тех пор, пока аргумент не окажется совместимым. Этот блок и выполняется. Специальный вид catch

catch (...)

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

< Лекция 15 || Лекция 16: 123 || Лекция 17 >
Андрей Одегов
Андрей Одегов
Язык программирования C++
Елена Шумова
Елена Шумова

Здравствуйте! Я у Вас прошла курс Язык программировая Си++.

Заказала сертификат. Хочу изменить способ оплаты. Как это сделать?

Сергей Пантелеев
Сергей Пантелеев
Россия, Москва
Ахмет Арчаков
Ахмет Арчаков
Россия, Магас