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