На этом шаге мы рассмотрим общие принципы обработки исключений.
В стандартной библиотеке C++ применяется механизм обработки исключений. С его помощью можно обрабатывать экстренные ситуации, не "загромождая" интерфейс функции лишними аргументами или возвращаемыми значениями. При возникновении внештатной ситуации обычная последовательность обработки данных прерывается "генерированием исключения":
class Error; void f() { if (условие) { throw Error(): // Создать объект класса Error и передать } // в нем информацию об исключении . . . }
Команда throw запускает процесс, называемый раскруткой стека. Иначе говоря, программа выходит из всех блоков или фуикций так, как обычно происходит при выполнении команды return, однако при этом управление никуда не передается. Для всех локальных объектов, объявленных в блоках, из которых выходит программа, вызываются деструкторы. Раскрутка стека продолжается до тех пор, пока не произойдет выход из main() с завершением программы, либо исключение не будет "перехвачено" и обработано секцией catch:
int main() { try { . . . f(); . . . } catch (const Error&) { . . . // Обработка исключения } . . . }
В этом примере любое исключение типа Error, возникшее в блоке try, будет перехвачено секцией catch.
Объекты исключений представляют собой стандартные объекты, определяемые в виде обычных классов или базовых типов. Следовательно, вы можете передавать целые типы, строки или шаблоны, являющиеся частью иерархии классов. Обычно в программе создастся некое подобие иерархии специальных классов представляющих разные ошибки. В переменных этих объектов можно передать любую нужную информацию от места обнаружения ошибки к месту ее обработки. Обратите внимание: механизм называется обработкой исключений, а не обработкой ошибок. Эти два понятия не всегда эквивалентны. Например, ошибки в данных, введенных пользователем, нередко рассматриваются не как исключение, а как вполне типичное явление. Вероятно, в таких случаях ошибки пользовательского ввода стоит обработать локально с использованием традиционных средств обработки ошибок.
Чтобы указать, какие исключения могут генерироваться функцией, включите в ее объявление спецификацию исключений:
void f() throw(bad_alloc); // f() генерирует только исключения bad_alloc
Пустой список означает, что функция вообще не может создавать исключения:
void f() throw(); // f() не создает исключения
При нарушении спецификации исключений программа выполняет специальные действия.
В стандартную библиотеку включены некоторые общие средства обработки исключений, в том числе стандартные классы исключений и класс auto_ptr.
Более полную информацию по обработке исключений можно взять здесь.
На следующем шаге мы познакомимся с пространством имен.