Выбрать главу

catch (...) {

 // Обработка всех исключений

}

Здесь заключенное в круглые скобки многоточие обеспечивает совпадение с любым типом данных.

Использование формата catch(...) иллюстрируется в следующей программе.

// В этой программе перехватываются исключения всех типов.

#include <iostream>

using namespace std;

void Xhandler(int test)

{

 try {

  if(test==0) throw test; // генерирует int-исключение

  if(test==1) throw 'a'; // генерирует char-исключение

  if(test==2) throw 123.23; // генерирует double-исключение

 }

 catch (...) { // перехват всех исключений

  cout << "Перехват!\n";

 }

}

int main()

{

 cout << "НАЧАЛО\n";

 Xhandler (0);

 Xhandler (1);

 Xhandler (2);

 cout << "КОНЕЦ";

 return 0;

}

Эта программа генерирует такие результаты.

НАЧАЛО

Перехват!

Перехват!

Перехват!

КОНЕЦ

Как видите, все три throw-исключения перехвачены с помощью одной-единственной catch-инетрукции.

Зачастую имеет смысл использовать инструкцию catch(...) в качестве последнего "рубежа" catch-последовательности. В этом случае она обеспечивает перехват исключений "всех остальных" типов (т.е. не предусмотренных предыдущими catch-выражениями). Например, рассмотрим еще одну версию предыдущей программы, в которой явным образом обеспечивается перехват исключений целочисленного типа, а перехват всех остальных возможных исключений "взваливается на плечи" инструкции catch(...).

/* Использование формата catch (...) в качестве варианта "все остальное".

*/

#include <iostream>

using namespace std;

void Xhandler(int test)

{

 try {

  if(test==0) throw test; // генерирует int-исключение

  if(test==1) throw 'a'; // генерирует char-исключение

  if(test==2) throw 123.23; // генерирует double-исключение

 }

 catch(int i) {

  // перехватывает int-исключение

  cout << "Перехват " << i << '\n';

 }

 catch(...) {

  // перехватывает все остальные исключения

  cout << "Перехват-перехват!\n";

 }

}

int main()

{

 cout << "НАЧАЛО\n";

 Xhandler(0);

 Xhandler(1);

 Xhandler(2);

 cout << "КОНЕЦ";

 return 0;

}

Результаты, сгенерированные при выполнении этой программы, таковы.

НАЧАЛО

Перехват 0

Перехват-перехват!

Перехват-перехват!

КОНЕЦ

Как подтверждает этот пример, использование формата catch(...) в качестве "последнего оплота" catch-последовательности— это удобный способ перехватить все исключения, которые вам не хочется обрабатывать в явном виде. Кроме того, перехватывая абсолютно все исключения, вы предотвращаете возможность аварийного завершения программы, которое может быть вызвано каким-то непредусмотренным (а значит, необработанным) исключением.

Ограничения, налагаемые на тип исключений, генерируемых функциями

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