Б. Страуструп - Язык программирования С++. Специальное издание, 3-изд. Бином. 2004 (1160791), страница 97
Текст из файла (страница 97)
В 9 24.3.7.1 из- лозкены идеи использования инварпантов и утверждений для того, чтобы сделать вы- зов исключений более регулярным. 14.10. Стандартные исключения Приведем таблицу стандартных исключений, а также функций, операторов п общих средств, которые пх генерируют: Стандартные исключения (генерируются языком) Заголовочный файл Имя Чем генерируется Ссылка ЫоаРЫ агдитеп1 ооег)7озо еггог (оя Ьазе /а!!иге Библиотечные исключения являются частью иерархии классов, вершина которой— стандартный бцолпотечный класс исключений ехсерйоп, представленный в «яЫехсер1>: с!азя ехсеряоп ( риб!1с ехсериоп () гбгот (), ехсер лап (сопз1 ехсерноп 3) гбгот (); ехсериопй орега1ог= (сопя1 ехсер1!оп3) 1бгот (); ии1иа1-ехсеряоп () Ягою (); гяг1 на! сопя! сбаг' тба1 () сопя! Ягот 3; ргюа1е: //-.
); Эта иерархия выглядит следующим образом: ехсер поп 1оутс еггог 1еупгб еггог ~~~~" Йота!а еское/ ба<1 а!1ос оиг о/ капуе ба<1 ехсер11 гипнте еггог гапуе еггог ба<1 сазг Х< оиег/1ота еггог <1 1уреЫ ип<1ег/)озе еггог Ыя базе:/а!!иге !пиа!Ы агдитеп1 Это выглядит избыточно для организации восьми стандартных исключений. Однако данная иерархия пытается обеспечить основу н для исключений за пределами стан- Ьа<! а1!ос Ьаа санг Ьад 1уре1с1 Ьас( ехсерпоп ои1 о/ капуе пет Йупат(с спзг суреЫ спецификация исклюнения ог () Ьбхе1<%:орегнгог)) () конинууктор !Пгзе1 базе!<>:хо и!оку () юз Ьазе::с1еаг() й 6.2.6.2, й 19.4.5 й 15А.1.1 й 15А.4 6 14.6.3 6 3.7.2, й 1 6.3.3, 6 20.3.3 й 17.5.3 й 1 7.5.3.1 й 1 7.5.3.3 6 21.3.6 <пет> <1уре!и/о> <1уре!п/о> <ехсерноп> <яЫехсер1> <яЫехсер1> <зЫехсер1> <зЫехсер1> <Ыя> Глава 14. Обработка исключений 440 дартной библиотеки.
Логическими (1ой(с еггог) являются ошибки, которые в принципе можно перехватить либо до запуска программы, либо путем тестирования функций и конструкторов. Ошибками этапа выполнения (гнийте еггог) являются все остальные ошибки. Некоторые люди считают это полезной основой для всех ошибок и исключений, Я вЂ” нет, Классы исключений стандартной библиотеки не добавляют функции к набору, обеспечиваемому ехсерйоп; они просто определяют подходящим образом требуемые виртуальные функции. Таким образом, мы можем написать: иоЫ,Я ггу ( (/иснользовиниестандиртноа библиотеки сасссг (ехсерг(опб е) ( сонг « 'исключение стандартной библиотеки" «е ю(гас () « '~чп"; саСсЬ (...) ( соне « 'другое искл ючение1р"; 0- иоЫ региегеес( () ггу ( Мгою ехсераоп (), ~у рекурсивная генералик исключения сассБ (ехсереюпйе) ( региеггед (); свис «е.юсгае (); // рекурсивный еыгое функции Назначение оператора вывода состоит просто в том, чтобы предотвратить повторное использование компилятором памяти, занимаемой исключением с именем е.
Стандартные исключения являются производными от ехсерИоп. Однако этого нельзя сказать про все исключения, так что попытка перехвата всех исключений при помощи перехвата ехсерГ(оп была бы ошибочной. Аналогично, будет ошибкой предполагать, что каждое исключение, производное от ехсерг(оп, является исключением стандартной библиотеки: программисты могут добавлять свои собственныс исключения в перархшо ехсер((оп. Обратите внимание, что операции ехсерйоп сами не генерируют исключений. В частности из этого следует, что генерация исключения стандартной библиотеки не приведет к исключению бас( а((ос.
Механизм обработки исключений резервирует некоторое количество памяти для себя в пелях хранения исключений (возможно, в стеке). Естественно, можно написать код, который постепенно приведет к исчерпанию всей памяти в системе, вызвав таким образом сбой. Например, ниже приведена функция, которая, если будет вызвана, проверяет, кто первым исчерпает память: вызов функции пли обработка исключений: 441 14.11. Советы 14.11. Советы [1] Пользуйтесь исключениями для обработки ошибок; 9 14.1.
[2] Не пользуйтесь исключениями в случаях, когда достаточно локальных управляющих структур; 6 14.1. [3] Пользуйтесь принципом «выделение ресурса есть инициализация» для управления ресурсами; 9 14.4. [4] Не каждая программа должна быть безопасной с точки зрения исключении; 9 14А.З. [5[ Пользуйтесь прпнпнпом «выделение ресурса есть инициализация» и обработчиками исключений для поддержки инварнантов; 9 14.3,2. [6] Сводите к минимуму использование блоков !гп. Вместо явного кода обработки пользуйтесь прпнпипом «выделение ресурса есть инициализация»; з 14А. [7] 1-!е в каждой функции требуется обрабатывать все возможные ошибки; ~ 14.9.
[8] Генерируйте исключения для указания на ошибку в конструкторе; з 14А.6. [9] Перед генерапией исключения из выражения присваивания убедитесь в том, что все операнды останутся в корректном состоянии; 9 14А.6.2. [10] Избегайте генерации исключений в деструкторах; 9 14А.7. [11] Заставьге та!и [] перехватывать все исключения и сообщать о них; 9 14.7, [12] Разделяйте обычный код и код обработки ошибок; 6 14А5, 6 14.5. [13] Гарантируйте, что каждый ресурс, выделенный в конструкторе, освобождается прн возникновении исключения в этом конструкторе; 9 14.4.
[! 4] Управление ресурсами должно быть иерархическим; 9 14.4. [15] Пользуйтесь спецификацией исключений для важных интерфейсов; 9 14.9. [16] Опасайтесь утечек памяти, вызываемых выделением памяти при помощи оператора пеш без последующего освобождения при возникновении исключений; ~ 14А.1, ~ 14.4.2, ~ 14,4.4. [!7] С питайте, что каждое исключение, которое может быть сгенерировано функцией, будет сгенерировано; 9 14.6. [!8] Не предполагайте, что все исключения являются производными от класса ехсер!!оп; э 14.10. [19] Библиотека не должна волевым решением прекращать выполнение программы - - ей следует сгенерировать исключение и позволить принять решение вызывающей функции; 9 14.1. [20] Библиотека пе должна выводить диагностическую информацию коне шому пользоватсэпо — ей следует сгенерировать исключение н позволить принять решение вызывающей функции; 9 14.1, [21] Разрабатывэите стратегию обработки ошибок на ранних этапах проектирования; 3 14.9.
14.12 Упражнения 1. ( 2) Обобщите класс 8ТСЯ 14.6.3.1) до шаблона, который может использовать технику «выделение ресурса есть инициализация» для хранения и переустановки функций различных типов, 442 Глава 14. Обработка исключений 2 3 4 5 6 7 8 10 11. (*3) Завершите класс Р1г 1о Т из ~ 11.11 в виде гпаблона, который использует исключения для сигнализации об ошибках времени выполнения. (»3) Напишите функцию, осуществлякпцую поиск значения в узлах двоичнага дерева из сйаг*. Если узел, содержашпй слово «здравствуй», найден, функция 7?пс()"здравствуй") возвратит указатель на этот узел. Воспользуйтесь исключением д.чя индикации «не найдено». (*3) Определите класс 1п1, который ведет себя точно также, как встроенный тпп 1п1, за исключением тога, что он генерирует исключения, не допуская переполнения сверху пли снизу.
(*2.5) Возьмите базовые операции открытия, закрытия, чтения н записи из интерфейса С к вашей операционной системе и рса.шзуйте эквивалентные функции на С++, которые в случае возникновения ошибок генерирует исключения. (*2.5) Напишите законченный ц~аблон Уес(ог с исключениями Ровде (диапазон) и Иге (размер). (*1) ??аппшите ппкл, вычисляющий сумму Уес1огиз З 14.12[6), не проверяя размер вектора, Почему это плохая идея? (*2.5) Подумайте об использовании класса Ехсер1?от в качестве базового для всех классов, применяемых в качестве исключений. Как это может выглядеть? Как ато следует использовать? К чему хорошему это может привести? Какие недостатки возникают из-за требования использовать такой класс? (*1) Имеется 1л1слат ))11* ...
'/) Внесите такие изменения, чтобы все исключения перехватывались, преобразовывюгись в сообщения об ошибках, и затем выполнение завершалось по пбог1 )). Подсказка: функция спй угот С)) в ~ 14.9 не полностью обрабатывает все случаи. ('2) Напишите класс пли шаблон, подходяший для реалпзапип обратного вызова. (*2 5) Напишите класс Хоай (блокировка) для некотор оп парю тельной системы. Иерархии классов Абстракция — это выборочное невежество. — Эндрю Кениг Множественное наследование — разрешение неоднозначности наследование и азгпу-обьявления — повторяющиеся базовые классы— виртуальные базовые классы — использование множественного наследования — управление доступом — защищенные члены — доступ к базовым классам — информация о типе на этапе выполнения — динамическое приведение с1упат1с сав1 — статические и динамические приведения— приведение из виртуального базового класса — 1уреЫ вЂ” расширенная информация о типе — правильное и неправильное использование информации о типе на этапе выполнения — указатели на члены — свободная память — виртуальные конструкторы — советы — упражнения.
15.1. Введение и обзор В этой главе обсуждается, как производные классы и виртуальные функции взаимодействуют с другими средствами языка, такими как; управление доступом, поиск имен, управление свободной памятью, конструкторы, указатели и преобразования типов. Глава состоит из пяти основных разделов: э 15.2 Множественное наследование. ~ ! 5.3 Управление доступом. в 15А Определение типа во время выполнения. э 15.5 Указатели на члены. э 15.6 Использование свободной памяти. В общем случае, класс создается из решетки базовых классов.
Ввиду того, что исторически болыпинство таких решеток были деревьями, решетку классов часто называют иерархиеи классов. Мы пытаемся проектировать классы таким образом, чтобы пользователя без острой необходимости не интересовало, каким образом класс составляется из других классов. В частности, механизм виртуальных вызовов гарантирует, что когда мы вызываем функциюД)) для некоторого объекта, вызывается одна и та же функция, независимо от того, какой класс в иерархии содержи~ объявлениеД), использованное для вызова.