- •Санкт-Петербургский
- •Процедурное программирование
- •Объектно-ориентированное программирование
- •Обобщенное программирование
- •На пути к объектно-ориентированному программированию
- •Абстракция сущностей и процедурный язык программирования
- •Абстрактный тип данных
- •Организация класса
- •Определение и объявление класса
- •Члены класса
- •Маркеры доступа
- •Конструкторы
- •Понятие об объекте
- •Организация кода при работе с классами
- •Статические компоненты класса
- •Дружественные функции и дружественные классы
- •Особенности применения дружественных функций и классов
- •Перегрузка оператров
- •Перегрузка оператора присваивания
- •Реализация перегруженного оператора присваивания для класса Array
- •Перегрузка оператора индексирования
- •Понятие о константной функции
- •Константный вариант перегруженного оператора индексирования
- •Вычисление смешанных выражений
- •Наследование
- •Структура объекта порожденного класса
- •Доступ к элементам базового класса
- •Конструкторы порожденного класса
- •Порядок создания объекта порожденного класса
- •Перегруженный оператор присваивания порожденного класса
- •Вызов виртуальной функции из тела невиртуальной функции
- •Виртуализация функций не-членов класса
- •Идиома невиртуального интерфейса (nvi)
- •Реализация механизма виртуальных функций
- •Накладные расходы при работе с виртуальными функциями
- •Чисто виртуальные функции. Абстрактные базовые классы
- •Виртуальные деструкторы
- •Автономные и базовые классы
- •Дублирование подобъектов
- •Конструкторы при виртуальном наследовании
- •Работа с данными при виртуальном наследовании
- •Обработка исключительных ситуаций
- •Завершение или продолжение
- •Распределение обязанностей между разработчиком и клиентом
- •Генерация исключений
- •Объект исключения
- •Раскрутка стека
- •Спецификации исключений
- •Работа с обработчиками
- •Формат обработчика
- •Пример обработки исключений
- •Современная точка зрения на спецификации исключения
- •Шаблоны функций
- •Объявление и определение шаблона функции
- •Примеры объявлений и определений шаблонов функций
- •Инстанцирование шаблона функции
- •Неявное инстанцирование
- •Явное инстанцирование конкретной функции
- •Структура использования шаблона функции с явным инстанцированием
- •Перегрузка шаблона функции
- •Явная специализация шаблона функции
- •Шаблоны классов
- •Использование шаблона класса
- •Наследование и шаблоны
- •Шаблоны классов и отношение включения
- •Рекурсивное использование шаблонов классов
- •Друзья и шаблоны классов
- •Явная и частичная специализация шаблона класса
- •Алгоритмы
- •Алгоритм for_each
- •Функциональные объекты
- •Алгоритм copy
- •Алгоритм sort
- •Термины и определения
- •.Литература
Объект исключения
Объект исключения автоматически создается компилятором. Он строится на основе того объекта, который «выбрасывает» инструкция throw. Например:
throwstd::length_error(“Недопустимо большой размер ” “объекта \n”);
После того как отработает инструкция throw, временный анонимный объект будет уничтожен. Но перед его уничтожением компилятор снимет копию с этого временного объекта. Эта копия будет сохранена компилятором в надежном месте. Указанная копия и называется объектом исключения. Объект исключения доступен любому обработчикуcatch, который способен обрабатывать данный тип исключений.
После создания объекта исключения управление должно покинуть тело той функции, в которой сгенерировано исключение. Однако до этого события компьютер должен выполнить так называемую раскрутку стека (stack unwinding).
Раскрутка стека
В процессе раскрутки стека происходит уничтожение локальных объектов. Для локальных объектов, имеющих пользовательский тип, автоматически вызываются деструкторы. Для удаления локальных объектов, имеющих встроенный тип, компилятор ничего не делает. Для объектов, созданных с помощью оператора new, компилятор не будет автоматически вызывать операторdeleteс целью принудительного освобождения памяти.
Перейдем теперь к рассмотрению второй обязанности разработчика функции, которая состоит в том, что необходимо уведомить клиента о том какие исключения он должен обрабатывать. Одна из специальных возможностей предусмотрена стандартом языка C++. Эта возможность носит название спецификации исключения.
Спецификации исключений
Это необязательная конструкция. Программист может ее записывать в объявлении и определении функции. Для определенности будем рассматривать объявление (прототип) функции, которое с учетом спецификаций исключения будет иметь следующую структуру.
<α>[β];
Здесь α – заголовок функции, β – необязательная спецификация исключения. Отметим, что имеются два формата спецификаций исключения.
throw(γ), где γ – список типов исключений.
throw().
Второй формат спецификаций исключений используется в тех случаях, когда разработчик функции предполагает, что функция не будет выбрасывать исключения.
Приведем пример.
class A { }; class B { }; class C { }; void f() throw(A, B); void h() throw();
В программном коде этого примера вначале имеются определения трех классов исключений с именами A,B и С. Затем приводятся прототипы двух функций, которые содержат спецификации исключений. Предполагается, что функцияf()может выбросить исключения типаAи B. Функцияh()не должна выбрасывать исключений.
Теперь казалось бы все хорошо. Клиент знает, что ему необходимо создать два обработчика catch. Один из них должен обрабатывать исключения типаA, а второй обработчик – для типаB.
Но что произойдет в том случае, когда функция выбросит исключение класса C. Это может, например, произойти так:
void f() throw(A, B) { //.. g(); } void g() { //.. throw C(); }
Эта ситуация известна как выброс непредвиденного исключения. Возможность появления такой ситуации усложняет использование спецификаций исключения.