- •Список литературы по модулю
- •История языка C++
- •Основные особенности C++
- •Простые расширения языка C
- •Объявление переменных ссылочного типа
- •Инициализация и использование ссылок
- •Ссылки в формальных параметрах функций
- •Ссылки как возвращаемые значения функций
- •Константные ссылки
- •Объявление класса
- •Секции в объявлении класса
- •Пример: секции в объявлении класса
- •Объявление полей
- •Определения статических полей
- •Объявление методов
- •Виртуальные и абстрактные методы
- •Объявление конструкторов
- •Пример: объявление конструкторов
- •Создание объектов в динамической памяти
- •Создание массивов в динамической памяти
- •Удаление объектов и массивов
- •Объявление деструктора
- •Пример: объявление деструктора
- •Объекты в автоматической памяти
- •Пример: автоматический вызов деструктора
- •Пример: автоматический вызов деструктора (продолжение)
- •Объекты в глобальной памяти
- •Объекты в полях других объектов
- •Пример: объекты в полях других объектов
- •Проблема копирования объектов
- •Объявление конструктора копий
- •Перегруженная операция присваивания
- •Основной способ наследования в C++
- •Пример: одиночное наследование
- •Переопределение методов
- •Пример: переопределение методов
- •Динамическое приведение типов
- •Пример: динамическое приведение типов не всегда допустимо
- •Пример: динамическое приведение типов
- •private- и protected-наследование
- •Наследование от нескольких базовых классов
- •Иерархия наследования и классы противоречия
- •Неоднозначности в противоречивых иерархиях
- •Разрешение неоднозначностей
- •Основная проблема противоречивых иерархий
- •Виртуальное наследование
- •Пример: виртуальное наследование
- •Понятие шаблона
- •Типовые формальные параметры шаблона
- •Нетиповые формальные параметры шаблона
- •Шаблонные формальные параметры шаблона
- •Значения параметров шаблона по умолчанию
- •Зависимые идентификаторы в шаблоне
- •Инстанциация шаблонов
- •Выведение фактических параметров при инстанциации шаблона функции
- •Требования к фактическим параметрам шаблонов
- •Специализация шаблона функции
- •Пример: специализация шаблона функции
- •Пример: перегрузка имеет больший приоритет, чем специализация
- •Cпециализация шаблона класса
- •Пример: специализация шаблона класса
- •Частичная специализация шаблона класса
- •Вычисления во время компиляции
- •Пример: возведение числа в степень
- •Понятие перегрузки операций
- •Ассортимент перегружаемых операций
- •Перегрузка операции присваивания
- •Операция присваивания возвращает левое значение
- •Составные операции присваивания
- •Перегрузка бинарных арифметических операций
- •Перегрузка операций сравнения
- •Перегрузка операций с помощью функций
- •Перегрузка унарных операций
- •Перегрузка операции приведения типа
- •Исключения
- •Оператор throw
- •Пример: оператор throw
- •Синтаксис try- и catch-блоков
- •Пример: перехват исключения std::bad_alloc
- •Жизненный цикл объектов-исключений
- •Пример 1: жизненный цикл объектов-исключений
- •Пример 2: жизненный цикл объектов-исключений
- •Пример 3: жизненный цикл объектов-исключений
- •Пример: уничтожение автоматических объектов в процессе передачи исключения в catch-блок
- •Перехват исключений в инициализаторах конструкторов
- •Пример: перехват исключений в инициализаторах конструкторов
- •Спецификатор throw в заголовках функций
- •Пример 1: спецификатор throw
- •Пример 2: спецификатор throw
- •Спецификатор throw и переопределение виртуальных методов
- •Создание классов исключений
- •Пример: создание классов исключений
Пример: уничтожение автоматических объектов в процессе передачи исключения в catch-блок
Базовые |
1 |
|
|
||
сведения |
2 |
|
Обобщённое |
3 |
|
|
||
программирова- |
4 |
|
ние |
||
5 |
||
Перегрузка |
||
6 |
||
операций |
||
|
||
Исключения |
7 |
|
|
||
Порождение |
8 |
|
|
||
Перехват и |
9 |
|
|
||
обработка |
10 |
|
|
||
Спецификация |
11 |
|
|
||
Класс exception |
12 |
|
|
||
|
13 |
|
|
14 |
|
|
15 |
|
|
16 |
|
|
17 |
|
|
18 |
# include < iostream >
struct Dummy { ~ Dummy (); };
Dummy ::~ Dummy () |
{ std :: cout << "# "; } |
||
void recur ( int n) { |
|
||
if (n |
== 0) |
throw |
" base of recursion "; |
Dummy |
d; |
|
|
recur (n -1); |
|
|
|
std :: cout << |
" should never be reached !"; |
||
} |
|
|
|
int main () |
|
|
|
{ |
|
|
|
try { |
recur (10); |
} catch (...) { } |
|
return |
0; |
|
|
} |
|
|
|
Вывод:
# # # # # # # # # #
91 / 99
Перехват исключений в инициализаторах конструкторов
Базовые
сведения
Обобщённое программирова- ние
Перегрузка
операций
Исключения
Порождение
Перехват и
обработка
Спецификация
Класс exception
Напомним, что конструкторы в C++ могут иметь списки инициализаторов, в которых вызываются конструкторы объектов, расположенных в полях, и конструкторы базовых классов.
Так как конструкторы полей и базовых классов могут порождать исключения, нужно уметь эти исключения перехватывать, например, для протоколирования неудачного создания объектов в логах. Для этой цели служат специальные try-блоки, обрамляющие тело конструктора, которые синтаксически выглядят как
Класс :: Класс ( параметры_конструктора ) try
:список_инициализации
{тело_конструктора }
catch ( исключение ) { тело_обработчика_исключения }
...
Отметим, что если catch-блок не оканчивается порождением другого исключения, старое исключение не уничтожается и передаётся дальше.
Пример: перехват исключений в инициализаторах конструкторов
Базовые |
1 |
|
|
||
сведения |
2 |
|
Обобщённое |
3 |
|
|
||
программирова- |
4 |
|
ние |
||
5 |
||
Перегрузка |
||
6 |
||
операций |
||
|
||
Исключения |
7 |
|
|
||
Порождение |
8 |
|
|
||
Перехват и |
9 |
|
|
||
обработка |
10 |
|
|
||
Спецификация |
11 |
|
|
||
Класс exception |
12 |
|
|
||
|
13 |
|
|
14 |
|
|
15 |
|
|
16 |
|
|
17 |
|
|
18 |
|
|
19 |
|
|
20 |
# include |
< iostream > |
|
|
using namespace |
std ; |
|
|
struct A |
{ A( int |
x ); |
}; |
struct B: |
public |
A { |
B( int x ); }; |
A :: A( int |
x) { if |
(x |
< 0) throw " negative "; } |
B :: B( int x) try : A(x) { }
catch ( const char *s) { cout << "1 "; }
int main ()
{
try {
Bb ( -10);
}catch (...) { cout << " 2\ n";
}
return 0;
}
1 2
93 / 99
Спецификатор throw в заголовках функций
Базовые
сведения
Обобщённое программирова- ние
Перегрузка
операций
Как и в языке Java, в C++ можно перечислить типы исключений, которые может порождать вызов функции. Для этого после списка формальных параметров следует разместить спецификатор throw:
Исключения
Порождение
Перехват и
обработка
Спецификация
Класс exception
throw ( список типов исключений )
Семантика этого спецификатора несколько отличается от семантики соответствующей конструкции языка Java, а именно:
!вызов функции, для которой разрешённые исключения не указаны, может порождать любые исключения;
!вызов функции со спецификатором throw() не порождает никаких исключений;
!компилятор не следит за тем, какие исключения порождаются внутри функции: вместо этого неразрешённые исключения просто не могут выйти за пределы функции и приводят к аварийному завершению программы.
94 / 99