Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Шпора 57стр.doc
Скачиваний:
54
Добавлен:
15.06.2014
Размер:
478.21 Кб
Скачать

Вопрос 40. Генерация исключений. Повторная генерация исключений.

Ключевое слово throw используется для того, чтобы указать, какое исключение генерируется. Это называется генерацией исключения или возбуждением исключения. Обычно throw имеет один операнд. Операнд throw может быть любого типа.

После генерации исключение будет перехвачено ближайшим обработчиком исключений (ближайшим к блоку try, в котором было сгенерировано исключение). Обработчики исключений для блока try перечисляются сразу после него.

Может оказаться, что сам блок try не содержит никаких проверок ошибок и не включает никаких операторов throw, но код, вызываемый из блока try, может содержать контроль ошибок, например, в конструкторах.

Исключение может прервать выполнение программы, но это не обяза­тельно. Однако, выполнение блока, в котором сгенерировано исключение, завершается.

Повторная генерация исключений

Если обработчик, который перехватил исключение, не может обработать его, обработчик может потребовать освободить ресурсы прежде, чем проводить дальнейшую обработку. В этом случае обработчик может просто повторно сгенерировать это исключение оператором throw;

Такой оператор throw без аргументов повторно генерирует то же самое исключение. Если никакое исключение не было сгенерировано, то оператор повторной генерации вызывает обращение к функции завершения terminate. Т.е. оператор throw должен появляться только в обработчике catch; в противном случае, он вызовет обращение к terminate.

Но даже если обработчик может обработать исключение и независимо от того, делает ли он какую-либо обработку этого исключения, он может повторно возбудить исключение для последующей обработки его вне этого обработчика.

Повторно сгенерированное исключение обнаруживается следующим внешним блоком try и перехватывается обработчиком из списка, следующего за этим внешним блоком try.

{ for(;;) { try

{ cout<<"…"<<endl }

catch(char *s)

{ cout<<” …. "<<endl; }

}

}

Вопрос 41. Перехват исключений.

try {

// Фрагмент, который может инициировать исключения

}

catch (Exception_Type t) {

// Восстановление после исключения типа Exception_Type

}

catch (...) {

// Восстановление после исключений всех остальных типов

}

Обработчики исключений содержатся в блоках catch. Каждый блок catch начинается с ключевого слова catch, за которым следуют круглые скобки, содержащие тип и необязательное имя параметра. Затем в фигурных скобках записываются операторы обработки исключения. Когда исключение перехвачено, начинает выполняться программа в блоке catch.

Исключение, у которого тип сгенерированного объекта соответствует типу аргумента в заголовке catch, вызывает выполнение программы обработки этого блока catch.

Исключение перехватывается первым обработчиком catch, следующим за активным в настоящее время блоком try и соответствующим типу сгенерированного объекта.

Исключение, которое не перехвачено, вызывает terminate, что по умолчанию приводит к вызову abort для аварийного завершения программы.

Если после catch в круглых скобках записано многоточие: catch (...) это означает, что будут перехватываться все исключения.

Возможно, что некоторому сгенерированному объекту не будет соответствовать ни один обработчик. Это вызывает продолжение поиска соответствия в следующем внешнем блоке try, включающем данные. При продолжении этого процесса в конечном счете может быть выяснено, что в программе не существует обработчика, который соответствовал бы типу сгенерированного объекта; в этом случае вызывается функция terminate, которая по умолчанию вызывает функцию abort

Обработчики исключений поочередно просматриваются в поисках соответствующего типа.

Возможно, что данному типу исключения будут соответствовать несколько обработчиков исключений. В этом случае выполняется первый обработчик, соответствующий типу исключения. Если данному типу соответствуют несколько обработчиков и если они отличаются друг от друга, то последовательность записи обработчиков будет влиять на способ, к-ым эти исключения будут обрабатываться.

Несколько обработчиков catch содержат тип класса, к-ый соответствует типу конкретного сгенерированного объекта,т.к.

  • существует обработчик catch (...), к-ый перехватит любое исключение.

  • из-за иерархии наследования объект производного класса может быть перехвачен как обработчиком данного класса, так и обработчиком любого базового класса, от к-ого порожден данный класс.

Иногда программа может обрабатывать многие близко связанные типы исключений. В этом случае можно создать один класс исключения и один обработчик catch для группы исключений.

Тип параметра в заголовке catch соответствует типу сгенерированного объекта, если:

  • они имеют одинаковый тип;

  • тип параметра обработчика catch явл-ся открытым базовым классом класса сгенерированного объекта;

  • параметр обработчика имеет тип указатель, и сгенерированный объект тоже имеет тип ук-ль, преобразуемый в тип параметра путем допустимых преобразований указателей. Например, указатель производного класса преобразуется в указатель базового класса стандартными операциями преобразования;

  • обработчик catch записан в форме catch (...).

По умолчанию, если никакой обработчик для исключения не найден, программа завершается.

Способы написания обработчиков ошибок:

  • можно рассмотреть ошибку и решить вызвать функцию terminate.

  • можно преобразовать один тип исключения в другой, генерируя это другое исключение.

  • можно выполнить любые необходимые восстановления и продолжить выполнение с первого оператора после последнего обработчика исключения.

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

  • можно просто возвращать некоторое значение состояния в среду и т.д.

Последовательность обработчиков catch. Обработчики, к-рые перехватывают объекты производных классов, должны быть помещены перед обработчиками, к-рые перехватывают объекты базового класса.

Блок catch может обрабатывать ошибку способом, который дает возмож­ность программе продолжать выполняться правильно. Или блок catch может завершить программу.