Язык программирования C++. Вводный курс



         

Спецификации исключений - часть 2


// два объявления одной и той же функции

extern int foo( int = 0 ) throw(string);

// ошибка: опущена спецификация исключений

extern int foo( int parm ) { }

Что произойдет, если функция возбудит исключение, не перечисленное в ее спецификации? Исключения возбуждаются только при обнаружении определенных аномалий в поведении программы, и во время компиляции неизвестно, встретится ли то или иное исключение во время выполнения. Поэтому нарушения спецификации исключений функции могут быть обнаружены только во время выполнения. Если функция возбуждает исключение, не указанное в спецификации, то вызывается unexpected() из стандартной библиотеки C++, а та по умолчанию вызывает terminate(). (В некоторых случаях необходимо переопределить действия, выполняемые функцией unexpected(). Стандартная библиотека предоставляет механизм для этого. Подробнее см. [STRAUSTRUP97].)

Необходимо уточнить, что unexpected() не вызывается только потому, что функция возбудила исключение, не указанное в ее спецификации. Все нормально, если она обработает это исключение самостоятельно, внутри функции. Например:

void recoup( int op1, int op2 ) throw(ExceptionType)

{

   try {

      // ...

      throw string("we're in control");

   }

   // обрабатывается возбужденное исключение

   catch ( string ) {

      // сделать все необходимое

   }

}  // все хорошо, unexpected() не вызывается

Функция recoup()

возбуждает исключение типа string, несмотря на его отсутствие в спецификации. Поскольку это исключение обработано в теле функции, unexpected() не вызывается.

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

extern void doit( int, int ) throw(string, exceptionType);

void action ( int op1, int op2 ) throw(string) {

   doit( op1, op2 );   // ошибки компиляции не будет

   // ...

<


Содержание  Назад  Вперед