Бьерн Страуструп.
Язык программирования С++
233
// обработчик особой ситуации Vector::Range
// если do_something() завершится неудачно,
// нужно как-то среагировать на это
// сюда мы попадем только в том случае, когда
//
вызов do_something() приведет к вызову Vector::operator[]()
// из-за недопустимого значения индекса
}
//
...
}
Обработчиком особой ситуации называется конструкция
catch ( /* ... */ ) {
//
...
}
Ее можно использовать только сразу после блока, начинающегося служебным словом try, или сразу
после другого обработчика особой ситуации. Служебным является и слово catch. После него идет в
скобках описание, которое используется аналогично описанию формальных параметров функции, а
именно, в нем задается тип объектов, на которые рассчитан обработчик, и, возможно, имена
параметров (см. $$9.3). Если в do_something() или в
любой вызванной из нее функции произойдет
ошибка индекса (на любом объекте Vector), то обработчик перехватит особую ситуацию и будет
выполняться часть, обрабатывающая ошибку. Например, определения следующих функций приведут к
запуску обработчика в f():
void do_something()
{
//
...
crash(v);
//
...
}
void crash(Vector& v)
{
v[v.size()+10]; // искусственно вызываем ошибку индекса
}
Процесс запуска и перехвата особой ситуации предполагает просмотр цепочки вызовов от точки
запуска особой ситуации до функции, в
которой она перехватывается. При этом восстанавливается
состояние стека, соответствующее функции, перехватившей ошибку, и при проходе по всей цепочке
вызовов для локальных объектов функций из этой цепочки вызываются деструкторы. Подробно это
описано в $$9.4.
Если при просмотре всей цепочки вызовов, начиная с
запустившей особую ситуацию функции, не
обнаружится подходящий обработчик, то программа завершается. Подробно это описано в $$9.7.
Если обработчик перехватил особую ситуацию, то она будет обрабатываться и другие, рассчитанные на
эту ситуацию, обработчики не будут рассматриваться. Иными словами, активирован будет только тот
обработчик, который находится в самой последней вызывавшейся функции, содержащей
соответствующие обработчики. В
нашем примере функция f() перехватит Vector::Range, поэтому эту
особую ситуацию нельзя перехватить ни в какой вызывающей f() функции:
int ff(Vector& v)
{
try
{
f(v); //
в f() будет перехвачена Vector::Range
}
catch (Vector::Range) { //
значит сюда мы никогда не попадем
//
...
}
}
Бьерн Страуструп.
Язык программирования С++
234
Достарыңызбен бөлісу: