ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 13.12.2020
Просмотров: 4263
Скачиваний: 28
Глава 36. Обработка исключений <exception>
411
Эта функция устанавливает новый обработчик не специфициро-
ванного исключения, на который указывает параметр
ph
, и воз-
вращает адрес предыдущего обработчика не специфицированно-
го исключения.
Обработчик не специфицированного исключения, установленный
по умолчанию при запуске программы, указывает на функцию
terminate
, которая была описана в предыдущем разделе.
В листинге 36.2 приведен пример установки и вызова нового об-
работчика не специфицированного исключения. Как правило,
обработчик не специфицированного исключения освобождает
ресурсы, захваченные программой, и завершает исполнение про-
граммы.
Листинг 36.2. Установка и вызов обработчика
не специфицированного исключения
#include <iostream>
#include <exception>
using namespace std;
int* p;
void foo()
{
cout<< "val: " << *p << endl;
delete p;
}
void g() throw() { throw "Unexpected exception"; }
int main()
{
set_unexpected(foo);
p = new int(10);
g(); // val: 10
return 0;
}
Если функция-обработчик не специфицированного исключения
не выбрасывает исключения, которое специфицировано в списке
Часть IV. Стандартная библиотека языка программирования С++
412
исключений функции, то среда исполнения выполняет одно из
следующих действий:
если в списке исключений функции специфицировано исклю-
чение типа
std::bad_exception
, то среда исполнения програм-
мы выбрасывает исключение этого типа и ищет обработчик
этого исключения;
если в списке исключений функции не специфицировано ис-
ключение типа
std::bad_exception
, то среда исполнения про-
граммы вызывает функцию
terminate
.
Заметим, что некоторые компиляторы могут не поддерживать
обработку не специфицированных исключений и всегда вызывать
в этом случае функцию
terminate
.
36.6. Определение наличия
выброшенного исключения
Для определения того, существует ли в данный момент исключе-
ние, которое выброшено, но для которого еще не найден обра-
ботчик исключения, предназначена функция
uncaught_exception
,
которая имеет следующий прототип:
bool uncaught_exception();
В случае если такое исключение существует, функция возвраща-
ет значение
true
, в противоположном случае — значение
false
.
Функция
uncaught_exception
обычно используется в деструкто-
рах, которые могут выбросить исключение. Подробнее этот во-
прос рассмотрен в
разд. 15.7
.
Листинг 36.3. Определение наличия выброшенного исключения
#include <iostream>
#include <exception>
using namespace std;
struct Demo
{
~Demo()
Глава 36. Обработка исключений <exception>
413
{
if (uncaught_exception())
cout << "There is uncaught exception." << endl;
else
{
cout << "Exception is thrown." << endl;
throw "Exception";
}
}
};
int main()
{
try
{
Demo a;
{
Demo b;
} // Exception is thrown.
} // There is uncaught exception.
catch(char* str)
{
cout << str << " is catched." << endl;
}
return 0;
}
Г Л А В А
37
Классы стандартных
исключений <stdexcept>
В заголовочном файле stdexcept определены классы стандартных
исключений, которые могут быть сгенерированы средой испол-
нения программы или функциями из стандартной библиотеки.
Ниже приведены объявления этих классов:
namespace std
{
class logic_error;
class domain_error;
class invalid_argument;
class length_error;
class out_of_range;
class runtime_error;
class range_error;
class overflow_error;
class underflow_error;
}
Эти классы наследуются от класса
exception
и образуют иерар-
хию классов, которая приведена на рис. 37.1.
Кратко опишем ситуации, в которых генерируются эти стандарт-
ные исключения:
logic_error
— логические ошибки в программе;
domain_error
— аргумент вне области определения;
invalid_argument
— неправильный аргумент функции;
Глава 37. Классы стандартных исключений <stdexcept>
415
Рис. 37.1.
Иерархия классов стандартных исключений
length_error
— длина превышает допустимую длину объ-
екта;
out_of_range
— аргумент вне диапазона значений;
runtime_error
— ошибки среды исполнения программы;
range_error
— значение функции не имеет представления;
overflow_error
— при выполнении арифметической опера-
ции получено очень большое числовое значение, которое
не имеет представления;
underflow_error
— при выполнении арифметической опе-
рации получено очень малое числовое значение, которое не
имеет представления.
При рассмотрении конкретных стандартных функций будет ука-
зано, какие исключения они могут генерировать. Теперь же более
подробно рассмотрим интерфейсы классов стандартных исклю-
чений. Для примера рассмотрим интерфейс класса
out_of_range
.
Остальные классы стандартных исключений имеют аналогичные
интерфейсы, за исключением того, что классы
logic_error
и
runtime_error
наследуются от класса
exception
.
Класс
out_of_range
имеет следующий интерфейс:
class out_of_range : public logic_error
{
public:
out_of_range(const string& what_arg);
};