- •2.5. Простейший ввод и вывод
- •2.5.1. Объект cin
- •2.5.2. Объект cout
- •2.5.3. Манипуляторы
- •2.6. Операторы для динамического выделения и освобождения памяти (new и delete)
- •5. Перегрузка
- •5.1. Перегрузка функций
- •5.2. Перегрузка операторов
- •5.2.1. Перегрузка бинарного оператора
- •5.2.2. Перегрузка унарного оператора
- •5.2.3. Дружественная функция operator
- •5.2.5. Перегрузка оператора []
- •5.2.6. Перегрузка оператора ()
- •5.2.8. Перегрузка операторов new и delete
- •6. Шаблоны
- •6.1. Параметризированные классы
- •6.2. Передача в шаблон класса дополнительных параметров
- •6.3. Шаблоны функций
- •6.4. Совместное использование шаблонов и наследования
- •6.5. Шаблоны класса и friend-функции
- •7.1. Организация ввода-вывода
- •7.2. Состояние потока
- •7.3. Строковые потоки
- •7.4. Организация работы с файлами
- •7.5. Организация файла последовательного доступа
- •Istream& seekg( streampos pos );
- •Istream& seekg( streamoff off, ios::seek_dir dir );
- •7.6. Создание файла произвольного доступа
- •7.7. Основные функции классов ios, istream, ostream
- •8.1. Основы обработки исключительных ситуаций
- •8.2. Перенаправление исключительных ситуаций
- •8.3. Исключительная ситуация, генерируемая оператором new
- •8.4 Генерация исключений в конструкторах
- •8.5. Задание собственной функции завершения
- •8.6. Спецификации исключительных ситуаций
- •8.7. Задание собственного неожиданного обработчика
- •8.8. Иерархия исключений стандартной библиотеки
8.6. Спецификации исключительных ситуаций
Иногда возникает необходимость заранее указать, какие исключения могут генерироваться в той или иной функции. Это можно сделать с помощью так называемой спецификации исключительных ситуаций. Это средство позволяет указать в объявлении функции типы исключительных ситуаций, которые могут в ней генерироваться. Синтаксически спецификация исключения является частью заголовочной записи функции и имеет вид:
объявление функции throw(тип1, тип2,…){тело функции}
где тип1, тип2,… − список типов, которые может иметь выражение throw внутри функции. Если список типов пуст, то компилятор полагает, что функцией не будет выполняться ни какой throw.
void fun(char c) throw();
Использование спецификации исключительных ситуаций не означает, что в функции не может быть сгенерирована исключительная ситуация некоторого не указанного в спецификации типа. Просто в этом случае программа по умолчанию завершится, так как подобные действия приведут к вызову неожиданного обработчика. Таким образом, когда функция генерирует исключительную ситуацию, не описанную в спецификации, выполняется неожиданный обработчик unexpected().
#include <iostream>
using namespace std;
#include <exception>
#include <stdlib.h>
class A {};
void ff(int i) throw(int,char*)
{ if(i==1) throw 1; // генерация исключения типа int
if(i==2) throw "aa"; // генерация исключения типа char*
if(i==3) throw A(); // генерация исключения типа объект класса A
}
int main()
{ try {
ff(3);
}
catch(int) { // обработчик исключения типа int
cout<<"int handler";
}
catch(char*) { // обработчик исключения типа int
cout<<"char* handler";
}
catch(A) { // обработчик исключения типа объект класса А
cout<<"class A handler";
}
return 0;
}
8.7. Задание собственного неожиданного обработчика
Так же как и обработчик terminate(), обработчик unexpected() позволяет перед завершением программы выполнить какие-то действия. Но в отличие от обработчика завершения неожиданный обработчик может сам генерировать исключительные ситуации. Таким образом, собственный неожиданный обработчик может сгенерировать исключительную ситуацию, на этот раз уже входящую в спецификацию. Установка собственного неожиданного обработчика выполняется с помощью функции set_unexpected().
Приведенная ниже программа демонстрирует применение спецификации исключений и перехват неожиданных исключительных ситуаций с помощью собственного обработчика.
#include <iostream>
using namespace std;
#include <exception>
class first{};
class second : public first{};
class third : public first{};
class my_class{};
void my_unexpected()
{ cout<<"my_unexpected handler"<<endl;
throw third(); // возбуждение исключения типа объект
} // класса third
void f(int i) throw(first) // указание спецификации исключения
{ if(i ) throw second(); //
else throw my_unexpected();
}
int main()
{ set_unexpected(my_unexpected);
try {
f(1);
}
catch(first) {
cout<<"first handler"<<endl;
}
catch(my_class) {
cout<<"my_class handler"<<endl;
}
try{
f(0);
}
catch(first) {
cout<<"first handler"<<endl;
}
catch(my_class) {
cout<<"my_class handler"<<endl;
}
return 0;
}
Результат выполнения программы:
first handler
my_unexpected handler
first handler
В данной программе вызов функции f() во втором блоке try приводит к тому, что генерируется исключительная ситуация, тип которой не указан в спецификации, поэтому вызывается установленный нами неожиданный обработчик, где происходит генерация исключения, которая успешно обрабатывается.