- •Содержание
- •ВВЕДЕНИЕ
- •1.ОБЪЕКТНО-ОРИЕНТИРОВАННЫЙ ПОДХОД
- •2. ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ
- •2.1. Абстрактные типы данных
- •2.2. Базовые принципы объектно-ориентированного программирования
- •2.3. Основные достоинства языка С++
- •2.4. Особенности языка С++
- •2.4.1. Ключевые слова
- •2.4.2. Константы и переменные
- •2.4.3. Операции
- •2.4.4. Типы данных
- •2.4.5. Передача аргументов функции по умолчанию
- •2.5.1. Объект cin
- •2.5.2. Объект cout
- •2.5.3. Манипуляторы
- •3.1. Объекты
- •3.2. Понятие класса
- •3.3. Конструктор копирования
- •3.4. Конструктор explicit
- •3.5. Указатель this
- •3.6. Встроенные функции (спецификатор inline)
- •3.7. Организация внешнего доступа к локальным компонентам класса (спецификатор friend)
- •3.8. Вложенные классы
- •3.9. Static-члены (данные) класса
- •3.10. Компоненты-функции static и const
- •3.11. Proxi-классы
- •3.12. Ссылки
- •3.12.1. Параметры ссылки
- •3.12.2. Независимые ссылки
- •3.13. Пространства имен
- •3.13.3. Ключевое слово using как объявление
- •3.13.4. Псевдоним пространства имен
- •3.14. Практические приемы ограничения числа объектов класса
- •4. НАСЛЕДОВАНИЕ
- •4.1.1. Конструкторы и деструкторы при наследовании
- •4.2. Виртуальные функции
- •4.3. Абстрактные классы
- •4.4. Виртуальные деструкторы
- •4.6. Виртуальное наследование
- •5.2. Перегрузка операторов
- •5.2.2. Перегрузка унарного оператора
- •5.2.3. Дружественная функция operator
- •5.2.4. Особенности перегрузки операции =
- •5.2.5. Перегрузка оператора []
- •5.2.6. Перегрузка оператора ()
- •5.2.7. Перегрузка оператора ->
- •5.2.8. Перегрузка операторов new и delete
- •5.3. Преобразование типа
- •5.3.1. Явные преобразования типов
- •6. ШАБЛОНЫ
- •6.1. Параметризированные классы
- •6.2. Передача в шаблон класса дополнительных параметров
- •6.3. Шаблоны функций
- •6.4. Совместное использование шаблонов и наследования
- •6.5. Шаблоны класса и friend-функции
- •6.6. Некоторые примеры использования шаблона класса
- •6.6.1. Реализация smart-указателя
- •6.6.2. Задание значений параметров класса по умолчанию
- •7.2. Состояние потока
- •7.3. Строковые потоки
- •7.4. Организация работы с файлами
- •7.5. Организация файла последовательного доступа
- •7.6. Создание файла произвольного доступа
- •7.7. Основные функции классов ios, istream, ostream
- •8. ИСКЛЮЧЕНИЯ В С++
- •8.2. Перенаправление исключительных ситуаций
- •8.3. Исключительная ситуация, генерируемая оператором new
- •8.6. Спецификации исключительных ситуаций
- •8.7. Задание собственного неожиданного обработчика
- •9. СТАНДАРТНАЯ БИБЛИОТЕКА ШАБЛОНОВ (STL)
- •9.3. Категории итераторов
- •9.4. Операции с итераторами
- •9.5. Контейнеры последовательностей
- •9.5.2. Контейнер последовательностей list
- •9.5.3. Контейнер последовательностей deque
- •9.6. Ассоциативные контейнеры
- •9.6.1. Ассоциативный контейнер multiset
- •9.6.2. Ассоциативный контейнер set
- •9.6.3. Ассоциативный контейнер multimap
- •9.7.1. Адаптер stack
- •9.7.2. Адаптер queue
- •9.7.3. Адаптер priority_queue
- •9.8. Алгоритмы
- •9.8.1. Алгоритмы сортировки sort, partial_sort, sort_heap
- •9.8.2. Алгоритмы поиска find, find_if, find_end, binary_search
- •9.8.3. Алгоритмы fill, fill_n, generate и generate_n
- •9.8.4. Алгоритмы equal, mismatch и lexicographical_compare
- •9.8.6. Алгоритмы работы с множествами
- •9.8.7. Алгоритмы swap, iter_swap и swap_ranges
- •9.8.8. Алгоритмы copy, copy_backward, merge, unique и reverse
- •10. ПРИМЕРЫ РЕАЛИЗАЦИИ КОНТЕЙНЕРНЫХ КЛАССОВ
- •10.1. Связанные списки
- •10.1.1. Реализация односвязного списка
- •10.2. Реализация бинарного дерева
- •11. ПРОГРАММИРОВАНИЕ ДЛЯ WINDOWS
- •11.1. Система, управляемая сообщениями
- •11.2. Управление графическим выводом
- •11.3. Контекст устройства
- •11.3.1. Экран
- •11.3.2. Принтер
- •11.3.3. Объект в памяти
- •11.3.4. Информационный контекст
- •11.4. Архитектура, управляемая событиями
- •11.5. Исходный текст программы
- •11.7. Некоторые новые типы данных
- •11.8. Венгерская нотация
- •11.9. Точка входа программы
- •11.11. Создание окна
- •11.12. Цикл обработки сообщений
- •11.13. Оконная процедура
- •11.14. Обработка сообщений
- •11.15. Обработка сообщений функцией DefWindowProc
- •11.16. Синхронные и асинхронные сообщения
- •11.17. Еще один метод получения описателя контекста устройства
- •11.19. Полосы прокрутки
- •Литература
Если программа не может найти подходящий обработчик для сгенериро- ванной исключительной ситуации, то будет вызвана процедура завершения terminate() (ее также называют обработчиком завершения), по умолчанию вы-
полнение программы будет остановлено и на экран будет выведено сообщение «Abnormal program termination». Однако можно установить собственный обра- ботчик завершения, используя функцию set_terminate(), единственным аргумен- том которой является указатель на новую функцию завершения (функция, при- нимающая и возвращающая void), а возвращаемое значение – указатель на пре-
дыдущий обработчик. Ниже приведен пример установки собственного обработ- |
||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Р |
чика завершения и генерации исключительной ситуации, для которой не может |
||||||||||||||
быть найден обработчик. |
|
|
|
|
|
|
|
|
||||||
|
#include <iostream> |
|
|
|
|
|
У |
|
||||||
|
using namespace std; |
|
|
|
|
|
|
И |
||||||
|
#include <exception> |
|
|
|
|
|
|
|||||||
|
#include <stdlib.h> |
|
|
|
|
|
|
|||||||
|
void my_term() |
|
|
|
|
Б |
|
|
|
|||||
|
{ |
cout<<"Собственная функция-обработчик"; |
|
|
|
|||||||||
|
} |
exit(1); |
|
|
|
|
а |
Г |
|
|
||||
|
|
|
|
|
|
|
|
|
|
|
|
|||
|
|
|
|
|
|
|
к |
|
|
|
|
|
||
|
int main() |
|
|
|
|
|
|
|
|
|||||
|
|
|
|
|
|
|
|
|
|
|
||||
|
{ |
|
set_terminate(my_term); |
|
|
|
|
|
|
|
||||
|
|
|
try { |
|
|
е |
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
throw 1; |
// ген рация ис лючительной ситуации типа int |
|||||||||
|
|
} |
|
|
т |
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
|
catch(char) { |
// брабо чик для типа |
char |
|
|
|
|||||||
|
|
|
|
cout<<"char handler"; |
|
|
|
|
|
|
|
|||
|
|
} |
и |
|
|
|
|
|
|
|
|
|
||
|
|
return 0; |
о |
|
|
|
|
|
|
|
|
|||
|
} |
|
|
л |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Резу ьтат выполнения программы: |
|
|
|
|
|
||||||||
|
Со ственная функция-обработчик |
|
|
|
|
|
||||||||
и |
|
|
|
|
|
|
|
|
|
|
|
|
||
Б |
б8.6. Спецификации исключительных ситуаций |
|
|
|||||||||||
|
Иногда возникает необходимость заранее указать, какие исключения мо- |
гут генерироваться в той или иной функции. Это можно сделать с помощью так называемой спецификации исключительных ситуаций. Это средство позволяет указать в объявлении функции типы исключительных ситуаций, которые могут в ней генерироваться. Синтаксически спецификация исключения является ча- стью заголовочной записи функции и имеет вид:
объявление функции throw(тип1, тип2,…){тело функции}
179
где тип1, тип2,… − список типов, которые может иметь выражение throw внут- ри функции. Если список типов пуст, то компилятор полагает, что функцией не будет выполняться никакой throw.
void fun(char c) throw();
Использование спецификации исключительных ситуаций не означает, что
в функции не может быть сгенерирована исключительная ситуация некоторого не указанного в спецификации типа. Просто в этом случае программа по умол- чанию завершится, так как подобные действия приведут к вызову неожиданно- го обработчика. Таким образом, когда функция генерирует исключительную си- туацию, не описанную в спецификации, выполняется неожиданный обработчик unexpected().
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 {
180
} |
|
|
|
|
|
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 приводит к |
|||||
тому, что генерируе ся исключиельная ситуация, |
тип которой не указан в спе- |
цификации, поэт му вызывае ся установленный нами неожиданный обработ-
чик, где происход |
генерация исключения, которая успешно обрабатывается. |
||
|
|
|
т |
|
|
о |
|
8.8. Иерарх я сключений стандартной библиотеки |
|||
Вершиной |
ерархии является класс exceptioh (определенный в заголовоч- |
||
|
ит |
|
|
л |
|
|
|
б |
|
|
|
ном фай е <exception>). В этом классе содержится функция what(), переопреде- ляемая в каждом производном классе для выдачи сообщения об ошибке.
Б |
Непосредственными производными классами от класса exception являют- |
|
ся классы runtime_error и logic_error (определенные в заголовочном файле |
||
<stdexcept>),и |
имеющие по несколько производных классов. |
Производными от exception также являются исключения: bad_alloc, гене-
рируемое оператором new, bad_cast, генерируемое dynamic_cast, и bad_typeid,
генерируемое оператором typeid.
Класс logic_error и производные от него классы (invalid_argument,
length_error, |
out_of_range) указывают на логические ошибки (передача непра- |
вильного аргумента функции, выход за пределы массива или строки). |
|
Класс |
runtime_error и производные от него (overflow_error и |
|
181 |