Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Создание эффективных приложений для Windows Джеффри Рихтер 2004 (Книга).pdf
Скачиваний:
376
Добавлен:
15.06.2014
Размер:
8.44 Mб
Скачать

Послетою как Вы скроете и это окно, процесс нормально завершится, посколь ку функция WinMain вернет управление. Заметьте, что данное окно не появляется при аварийном завершении процесса.

ГЛАВА 24 Фильтры и обработчики исключений

Исключение — это событие, которого Вы не ожидали. В хорошо написанной про грамме не предполагается попыток обращения по неверному адресу или деления на нуль И все же такие ошибки случаются За псрехват попыток обращения по неверно му адресу и деления на нуль отвечает центральный процессор, возбуждающий исклю чения в ответ на эти ошибки. Исключение, возбужденное процессором, называется аппаратным (hardware exception) Далее мы увидим, что операционная система и прикладные программы способны возбуждать собственные исключения — программ ные (software exceptions).

При возникновении аппаратного или программного исключения операционная система дает Вашему приложению шанс определить его тип и самостоятельно обра ботать Синтаксис обработчика исключений таков:

__try {

// защищенный блок

}

__except (фильтр исключений) {

// обработчик исключений

}

Обратите внимание на ключевое слово _ except За блоком try всегда должен сле довать либо блок finaly, либо блок except. Для данного блока try нельзя указать одно временно и блок finaly, и блок except: к тому же за try не может следовать несколько блок finaly или except Однако try-finally можно вложить в try-except, и наоборот.

Примеры использования фильтров и обработчиков исключений

В отличие от обработчиков завершения (рассмотренных в предыдущей главе), филь тры и обработчики исключений выполняются непосредственно операционной сис темой — нагрузка на компилятор при этом минимальна. В следующих разделах я рас скажу, как обычно выполняются блоки try-except, как и когда операционная система проверяет фильтры исключений и в каких случаях она выполняет код обработчиков исключений.

Funcmeister1

Вот более конкретный пример блока try-except

DWORD Funcmeister1()

{

DWORD dwTemp

// 1 Что-то делаем здесь

...

__try

{

// 2 Выполняем какую-то операцию dwTemp = 0;

}

__except (EXCEPTION_EXECUTE HANDLER)

{

// обрабатываем исключение этит код никогда не выполняется

...

}

// 3 Продолжаем что то делать return(dwTemp)

}

В блоке try функции Funcmetsterl мы просто присваиваем 0 переменной dwTemp Такая операция не приведет к исключению, и поэтому код в блоке except никогда не выполняется Обратите внимание на такую особенность конструкция try-finally ведет себя иначе После того как переменной dwTemp присваивается 0, следующим испол няемым оператором оказывается return

Хотя ставить операторы return, goto, continue и break в блоке try обработчика за вершения настоятельно не рекомендуется, их применение в этом блоке не приводит к снижению быстродействия кода или к увеличению сго размера Использование этих операторов в блоке try, связанном с блоком except, не вызовет таких неприятностей, как локальная раскрутка

Funcmeister2

Попробуем модифицировать нашу функцию и посмотрим, что будет

DWORD Funcmeister2()

{

DWORD dwTemp = 0;

// 1 Нто-то делаем здесь

...

__try

{

// 2 Выполняем какую-то операцию

dwTemp = 5 / dwTemp;

// генерирурт исключение

dwTemp += 10;

// никогда не выполняется

}

__except ( /* 3 Проверяем фильтр */

EXCEPTION_EXECUTE_HANDLER)

{

// 4. Обрабатываем исключение

MessageBeep(0)

...

}

// 5 Продолжаем что-то делать

return(dwТemp); }

Рис. 24-1. Так система обрабатывает исключения

Инструкция внутри блока try функции Funcmeister2 пытается поделить 5 на 0. Перехватив это событие, процессор возбуждает аппаратное исключение Тогда опе рационная система ищст начало блока except и проверяет выражение, указанное в качестве фильтра