Г. Шилдт - Полный справочник по C++ (1109478), страница 76
Текст из файла (страница 76)
Й Обработка производных исключительных ситуаций /Г Перехват проызволных классов. «(пс1ийе <(овстеаю> цвтпд паюеврасе всй," с1авв В ( ); с1авв ЬЫ рцн11с В ( ): Хпс упа1п() ( р йеттуей; гту ( Часть й. Язык С++ Если исключительные ситуации описываются с помощью базового и производных ю(ассов, при работе с операторами снеси следует проявлять максимальную осторожность, поскольку оператор свес)ц соответствующий базовому классу, одновременно соответствует всем производным классам.
Таким образом, если необходимо перехватить исключительные ситуации базового и производных классов, в последовательности операторов свес)т производный класс следует обрабатывать первым. Если зтого не сделать, оператор свесь, соответству(ощий базовому классу исключительной ситуации, также будет перехватывать исключительные ситуации всех производных классов. Рассмотрим следующую программу. с)зхоы деххчедг сапов(В )з) соцс « "Перехват базового класса М'; ) сасс)з(0 е)) ( сапе « "Этот оператор не выполняется.
1п"г ) хегохп О; ) Поскольку объект аетатеа является экземпляром класса, производного от класса в, он будет перехвачен первым оператором саеси, а второй оператор свес)х никогда выполняться не будет. некоторые компиляторы а таких случаях вылают предупрехгление. Другие компиляторы вообще считают это ошибкой. Так или иначе, чтобы исправить эту ситуацию„следует поменять порядок следования операторов сакс)ь Тонкости обработки исключительных ситуаций Обработка исюпочительных ситуаций в языке С++ обладает дополнительными свойствами и нюансами, которые облегчают ее применение. Эти особенности описываются ниже. Перехват всех исключительных ситуаций В некоторых случаях нет смысла обрабатывать отлельные типы исключительных ситуаций, а необходимо перехватывать их все подряд.
Для этого достаточно применить следуюший вил оператора свес)х. саес'и(...) ( // Обрабасаиа всех искхючиваельиых смхуаций Эллипсис означает, что данный оператор перехватывает все исключительные ситуа- ции. Его применение иллюстрируется слелующей программой. // В этом примере перехватываются все исключительные ситуации. Вхпс1пде <аовехеаю> цвхпд паюезрасе вес)г уоЫ Х)ханс)1ех(1пс севе) ( сху ( хб(Севе==о) Спхоы Севег // Генерирует объект типа Гпг 11(севе==1) сйхои 'а': // Генерирует объект типа с)хах вхб(севе=.†.2) спхоы 123.23; // Генерирует объект типа боц)з1е ) сассп(...) ( // Перехват всех исключительных ситуации соцс « "Перехват! 1п"г ) хпс п1аап() ( соцс « "начало1п"; Глава 19.
Обработка исключительных ситуаций ХЬагь11ех (О) г ХЬапб1ег(1); ХЬапд1ех(2); соиг « "Конец"; тегигп 0; Результаты работы этой программы приведены ниже, начало Перехват! Перехват! Перехват! Конец Как видим, все три исключительные ситуации, сгенерированные операторами ситом, перехватываются одним оператором свесь. Оператор саесЬ(...) особенно полезен. если поставить его в конце послсловательности операторов саесЬ. В таком случае, даже если возникнет исключительная ситуация. нс предусмотренная программистом. она будет перехвачена последним оператором сассЬ.
Рассмотрим слегка измененный вариант предыдущей программы, в котором целочисленные исключительные ситуации перехватываются явно, а остальные ошибки отслеживаются оператором саесЬ(... ) . // В этом примере по умолчанию используется оператор сассЬ(...) Зьпс1ибе аьовхгеаю> ив1пс паюеврасе вхб; чоуб хьапб1ег[ьпс гсвг) ( сху ( 11(севе==О) гЬгон гевг; // Генерируется объект типа 1пс 11(генг==1) Сигом 'а'; // Генерируется объект типа сЬах 1Е(гевс==2) сЬгон 123.23; // Генерируется объект типа доиЬ1е ) сагсЬ(ьпг 1) [ // Перехват исключительной ситуации типа ьпс соиг « "Перехват целого числа1п"; сагсЬ(...)( // Перехват всех остальных исключительных ситуаций соиг « "Перехват(тп"; ) апг пеьп() сонг « 'Началотп" ХЬапб1ег(0); ХЬапб1ег(1): ХЬапб1ег (2); сонг « "Конец" гегигп О; ) Результаты работы этой программы представлены ниже.
Часть (!. Язык С++ Нечево Перехват целого числа Перехват! Перехват! перехват! Конец Этот пример демонстрирует, что применение оператора свссЬ(...) — ХОРоший способ перехватывать все исключительные ситуации, которые нежелательно обрабатывать явно. Кроме того, оператор саесЬ(...) предотвращает аварийное завершение программы при обнаружении необработанной исключительной ситуации.
Ограничения исключительных ситуаций Программист может ограничить типы исключительных ситуаций, которые может генерировать функция в других местах програмляы. Фактически можно вообще запретить функции генерировать какие бы то ни было исключительные ситуации. Для этою следует добавить в определение функции раздел енкоы. тип возврагчиеито зничення нмя функции(епипзк ирюментов) СЬгоы(список типов) е ц 1 ( // Это определение Функции означает, что она может генерировать лишь исключительные ситуации, перечисленные в сливке ти/юв. Попытка сгенерировать исключительную ситуацию любого другого типа приводит к аварийному завершению программы. Если необходимо запретить функции вообще генерировать любые исключительные ситуации, список типов следует оставить пустым.
Попытка сгенерировать исключительную ситуацию, не поддерживаемую Функцией, сопровождается вызовом стандартной функции ппвхресеей(). Затем по умолчанию вызывается функция вЬохе() „и программа завершается аварийно. Однако для непредвиденной исключительной ситуации можно предусмотреть собственный обработчик. Следующая программа демонстрирует ограничения на типы исключительных ситуаций, которые могут генерироваться функцией. // ограничение типов исключительных ситуаций, генерируемых функцией. $1пс1цйе <Говггеаю> пвтпп паюеярасе всй; // данная функция может генерировать лнюь исключительные // ситуации, имеющие типы тпс, сЬаг и йоцЬ1е.
уогй ХЬапй1ег(ьпе севе) снгоы(1пс, снах, йопбзе) 11(севе==о) сцгоы севе/ // Генерируется объект типа 1пс 11(сенс=--1) снгоы *а'; // Генерируется объект типа сЬаг 11(сенс==2) сьгоы 123.23; // Генерируется объект типа йоць1е ) ьпе юаьп() соцс кк "Начвлотп'; Глава 19. Обрабатхв нскаочительных ситуаций ХЬапа)1ет(О)! // Попробуйте также передать Функции // ХЬапо1ет() числа 1 и 2 ) сассЬ(1пс 1) ( соне кк "Перехват целого числа1п"! ) сасаЬ(а)!ат с) ( соне « 'Перехват строких" ! сава)! (с)оц)з1е е() ( соцс « 'Перехват действительного числа1п"! ) соцс « "Конец' теецгп О! ) В этой программе функция лзтатн>1ет() может генерировать лишь исюпочительные ситуации, имеющие типы хпе, сЬат и Поц)з1е. При попытке сгенерировать исключительную ситуацию любого другого типа программа завершается аварийно.
(Иначе говоря, вызывается функция цпекресеед().) Чтобы увидеть, как это проиаходит, >далите из списка типов спецификатор ьпе и повторите компиляцию программы. Важно четко понимать, что ограничения распространяются лишь на типы исключительных ситуаций, которые функция может генерировать в блоке ету. Иначе говоря, блоки ету, находящиеся внутри функции, могут генерировать любые исюпочительные ситуации. Таким образом, ограничения распространяются лишь на исключительные ситуации, генерируемые вне функции. В следующем примере функция хззюи>1ет() не может генерировать никаких исключительных ситуаций. // данная функция не может генерировать никаких // исключительных ситуаций! чоЫ Хцапд1ет(ьпе севе) сйтои() ( /* Следуюшие операторы больше не выполняютая Они приводят к аварийному завершению программы.
*/ 1т(севе==о) сЬтон севе! ьт(севе=-=1) с)!тон 'а'; ьт(севе==-2) сЬтои 123.23; Повторное генерирование исключительной ситуации Если возникает необходимость повторно возбудить исключительную ситуацию вну(ри ее обработчика, можно выполнить оператор е)!том, не указывая тип исключительной ситуации. В этом случае оператору ету/свесь передается текущая исключительная ситуация. Таким образом для одной и той же исключительной ситуации можно предусмотреть несколько обработчиков.
Допустим, один обработчик исключительной ситуации управляет однил! аспектом, а второй — остальными. Внутри блока сава)т (или функции, вызываемой из этого блока) можно лишь повторно сгенерировать исключительную ситуацию. В этом случае она передается не тому же самому оператор> сава)ц а следующему. Повторное генерировашие исключительной ситуации иллюстрируется следующей программой. Часть П. йзык С++ // Пример повторного генерирования исключительной ситуаь;ии. Ввпс1иде <1оаегеагп> овьпя пагьеерасе ве(); чоьг) Хлапб1ег() ( сгу ( антон 'Привет"; // Генерируется объект типа сваг * ) свес)з(сопле с)заг ") ( // Перехват объекта типа с)заг соое « "Перехват объекта типа с)заг * внутри функции Х)ъзпг)1ег1п"; тихон ; // Повторное генерирование обьекта типа сцаг // вне функции. йпс шазл() соое « "начало1п"; сгу х)гапб1ех()/ ) сагой(сопле спас *) соис « "Перехват объекта типа снах < в функции та1Мп"; соил « "Конец"; гесогп О; Результаты работы этой программы приводятся ниже, | Начало Перехват объекта типа сГ1аг * внутри функции Х)запг)1ег() Перехват объекта типа с)заг * внутри функции п1а1п() Конец ~ 3 Функции $епп~па$ео и ипехрес1ебо Как указывалось ранее, функции еегюзпеее() и цпекрееееб() вызываются в крайних случаях, т.е.
когда обработка исключительной ситуации выполняется неверно. Эти функции принадлежат стандартной библиотеке языка С++. Их прототипы показаны ниже. чоЫ сегтьпасе() чоуб опехрессеб() Для вызова этих функций необходим заголовок <енсере1оп>. Функция еехзазпаее() вызывается, если подсистема обработки исключительных ситуаций нс может обнаружить подходяц(ий оператор свес)ъ Кроме того, она вызывается, если программа пытается повторно сгенерировать исключительную ситуацюо, которая ранее никогда не генерировалась. Функция еехю1паее() вызывается также во многих других, более запуганных ситуациях.
Например, деструктор уничтожаемого объекта генерирует исключительную ситуацию в процессе раскручивания стека, который выполняется при генерирования дру~ой исключительной ситуации. Как правило. функция ветвь(зтаее() является последним средством обработки исключительной си- Глава 19. Обработка исключительных ситуаций гуацни, сели никакой другой обработчик не подходит. Г!о умолчанию функция сеха1пасе() вызывает функцию аЪохс(). Фуьькция ипехрессеьт(] вызывается при попытке генерировать исключительную снтуацьцо, нс указанную в разделе е]ьхоь<. По умолчанию функция ипехресееьт() выьываст фуьькциьо ееюадпаее().