Программирование

Содержание

Слайд 2

6. Исключения

Ю.И. Воротницкий. Программирование

Обработка исключений - средства языка программирования, предназначенные для

6. Исключения Ю.И. Воротницкий. Программирование Обработка исключений - средства языка программирования, предназначенные
описания реакции программы на нестандартные ситуации (ошибки времени выполнения и другие возможные проблемы), возникающие при исполнении программы и приводящие к невозможности или нецелесообразности дальнейшей работы в соответствии с основным алгоритмом программы. Такие нестандартные ситуации называют исключениями.
Примеры исключений:
Нулевое значение знаменателя при выполнении операции деления. Результат орперации не определен, поэтому его дальнейшее использование в программе невозможно.
Ошибка при считывании данных с внешнего устройства. Если данные невозможно ввести, любые дальнейшие операции с ними бессмысленны.
Запрос на ввод данных (например, нажатие клавиши на клавиатуре). Программа должна перейти к чтению данных, чтобы не потерять поступающую информацию.

Слайд 3

6. Исключения

Ю.И. Воротницкий. Программирование

В отсутствие собственного механизма обработки исключений для прикладных

6. Исключения Ю.И. Воротницкий. Программирование В отсутствие собственного механизма обработки исключений для
программ наиболее общей реакцией на любую исключительную ситуацию является немедленное прекращение выполнения с выдачей пользователю сообщения о характере исключения.
Альтернативной возможностью является игнорирование исключительной ситуации и продолжение работы, но такая тактика опасна, так как может привести к ошибочным результатам работы программы.
Обработка исключительных ситуаций самой программой заключается в том, что при возникновении исключительной ситуации, управление передаётся некоторому заранее определённому обработчику — блоку кода, процедуре, функции, которые выполняют необходимые действия.
.

Слайд 4

6. Исключения

Ю.И. Воротницкий. Программирование

Исключительные ситуации, возникающие при работе программы, можно разделить

6. Исключения Ю.И. Воротницкий. Программирование Исключительные ситуации, возникающие при работе программы, можно
на две группы: синхронные и асинхронные
Синхронные исключения могут возникнуть только в определённых, заранее известных точках программы. Ошибка деления на нуль, ошибка чтения файла — типичные синхронные исключения, так как возникают они только при выполнении соответствующих операций (соответственно, деления, чтения из файла и т.п.).
Асинхронные исключения могут возникать в любой момент времени и не зависят от того, какая конкретно инструкция программы выполняется Типичные примеры таких исключений: аварийный отказ питания или поступление новых данных.

Слайд 5

6. Исключения

Ю.И. Воротницкий. Программирование

Существует два принципиально разных механизма функционирования обработчиков исключений:
Обработка

6. Исключения Ю.И. Воротницкий. Программирование Существует два принципиально разных механизма функционирования обработчиков
с возвратом подразумевает, что обработчик исключения ликвидирует возникшую проблему и приводит программу в состояние, когда она может работать дальше по основному алгоритму. В этом случае после того, как выполнится код обработчика, управление передаётся обратно в ту точку программы, где возникла исключительная ситуация (либо на команду, вызвавшую исключение, либо на следующую за ней) и выполнение программы продолжается. Обработка с возвратом типична для обработчиков асинхронных исключений.
Обработка без возврата заключается в том, что после выполнения кода обработчика исключения управление передаётся в некоторое, заранее заданное место программы, и с него продолжается исполнение.
.

Слайд 6

6. Исключения

Ю.И. Воротницкий. Программирование

Существует два варианта обработки исключений: структурная и неструктурная

6. Исключения Ю.И. Воротницкий. Программирование Существует два варианта обработки исключений: структурная и
обработка.
Неструктурная обработка исключений реализуется путем регистрации функций или инструкций-обработчиков для каждого возможного типа исключения. Язык предоставляет программисту возможности регистрации обработчика и его разрегистрации. Регистрация «привязывает» обработчик к определённому исключению, разрегистрация — отменяет эту «привязку». Если исключение происходит, выполнение основного кода программы немедленно прерывается и начинается выполнение обработчика. По завершении обработчика управление передаётся либо в некоторую наперёд заданную точку программы, либо обратно в точку возникновения исключения (в зависимости от заданного способа обработки — с возвратом или без). Независимо от того, какая часть программы в данный момент выполняется, на определённое исключение всегда реагирует последний зарегистрированный для него обработчик. В некоторых языках зарегистрированный обработчик сохраняет силу только в пределах текущего блока кода (процедуры, функции), тогда процедура разрегистрации не требуется.

Слайд 7

6. Исключения

Ю.И. Воротницкий. Программирование

Конструкция структурной обработки исключений содержит блок контролируемого кода

6. Исключения Ю.И. Воротницкий. Программирование Конструкция структурной обработки исключений содержит блок контролируемого
и обработчик (обработчики) исключений. Такая конструкция имеет следующий вид:
НачалоБлока
// Контролируемый код
...
если (условие) то СоздатьИсключение Исключение2
...
Обработчик Исключение1
// Код обработчика для Исключения1
...
Обработчик Исключение2
// Код обработчика для Исключения2
...
ОбработчикНеобработанныхИсключений
// Код обработки ранее не обработанных исключений
...
КонецБлока
Блоки обработки исключений могут многократно входить друг в друга, как явно (текстуально), так и неявно (например, в блоке вызывается процедура, которая сама имеет блок обработки исключений). Если ни один из обработчиков в текущем блоке не может обработать исключение, выполнение данного блока немедленно завершается, и управление передаётся на ближайший подходящий обработчик более высокого уровня иерархии. Это продолжается до тех пор, пока обработчик не найдётся и не обработает исключение.

Слайд 8

6. Исключения

Ю.И. Воротницкий. Программирование

Блоки обработки исключений могут многократно входить друг в

6. Исключения Ю.И. Воротницкий. Программирование Блоки обработки исключений могут многократно входить друг
друга, как явно (текстуально), так и неявно (например, в блоке вызывается процедура, которая сама имеет блок обработки исключений).
Если ни один из обработчиков в текущем блоке не может обработать исключение, выполнение данного блока немедленно завершается, и управление передаётся на ближайший подходящий обработчик более высокого уровня иерархии. Это продолжается до тех пор, пока обработчик не найдётся и не обработает исключение.

Слайд 9

6. Исключения

Ю.И. Воротницкий. Программирование

Блоки обработки исключений могут многократно входить друг в

6. Исключения Ю.И. Воротницкий. Программирование Блоки обработки исключений могут многократно входить друг
друга, как явно (текстуально), так и неявно (например, в блоке вызывается процедура, которая сама имеет блок обработки исключений).
Если ни один из обработчиков в текущем блоке не может обработать исключение, выполнение данного блока немедленно завершается, и управление передаётся на ближайший подходящий обработчик более высокого уровня иерархии. Это продолжается до тех пор, пока обработчик не найдётся и не обработает исключение.

Слайд 10

6. Исключения

Ю.И. Воротницкий. Программирование

Язык C++ включает следующие возможности для работы с

6. Исключения Ю.И. Воротницкий. Программирование Язык C++ включает следующие возможности для работы
исключениями: создание защищенных блоков (try-блок) и перехват исключений (catch-блок); инициализация исключений (оператор throw).
Для сигнализации о возникновении исключительной ситуации программист может воспользоваться невнятным механизмом классификации исключений по типам, который предложен в стандарте языка, возбудить стандартное исключение (например, с помощью класса exception из стандартной библиотеки) или описать собственный тип исключения.
Язык C++ построен на доверии к программисту, и требует, чтобы ситуации, связанные, например, с отсутствием входного файла, обрабатывались самим программистом. Так, выполнение процедуры reset в Паскале для несуществующего файла приведет к ошибке выполнения, а в С++ открытие файлового потока с атрибутами ios::in | ios::nocreate будет выполнено без каких-либо дополнительных сообщений.

Слайд 11

6. Исключения

Ю.И. Воротницкий. Программирование

Однако ситуации, связанные с делением на ноль или

6. Исключения Ю.И. Воротницкий. Программирование Однако ситуации, связанные с делением на ноль
с обращением к неправильному адресу памяти, однозначно классифицируются как ошибки выполнения и приводят к аварийному завершению программы.
Для перехвата таких ошибок может быть использован простейший формат защищенного блока, который имеет вид
try {операторызащищенногоблока}
catch(…) {обработчикошибочнойситуации}
Рассмотрим пример перехвата такой ошибочной ситуации.
float k;
int i, j;

try {
i=j/(int)k;
}
catch(…) {
cout << “Ошибка (деление на ноль)” << endl;
}

Слайд 12

6. Исключения

Ю.И. Воротницкий. Программирование

Однако ситуации, связанные с делением на ноль или

6. Исключения Ю.И. Воротницкий. Программирование Однако ситуации, связанные с делением на ноль
с обращением к неправильному адресу памяти, однозначно классифицируются как ошибки выполнения и приводят к аварийному завершению программы.
Для перехвата таких ошибок может быть использован простейший формат защищенного блока, который имеет вид
try {операторызащищенногоблока}
catch(…) {обработчикошибочнойситуации}
Рассмотрим пример перехвата такой ошибочной ситуации.
float k;
int i, j;

try {
i=j/(int)k;
}
catch(…) {
cout << “Ошибка (деление на ноль)” << endl;
}

Слайд 13

6. Исключения

Ю.И. Воротницкий. Программирование

Однако ситуации, связанные с делением на ноль или

6. Исключения Ю.И. Воротницкий. Программирование Однако ситуации, связанные с делением на ноль
с обращением к неправильному адресу памяти, однозначно классифицируются как ошибки выполнения и приводят к аварийному завершению программы.
Для перехвата таких ошибок может быть использован простейший формат защищенного блока, который имеет вид
try {операторызащищенногоблока}
catch(…) {обработчикошибочнойситуации}
Рассмотрим пример перехвата такой ошибочной ситуации.
float k;
int i, j;

try {
i=j/(int)k;
}
catch(…) {
cout << “Ошибка (деление на ноль)” << endl;
}

Слайд 14

6. Исключения

Ю.И. Воротницкий. Программирование

Для возбуждения собственных исключений используется оператор
throw [ выражение

6. Исключения Ю.И. Воротницкий. Программирование Для возбуждения собственных исключений используется оператор throw
]
Тип выражения, указанного в операторе throw, определяет тип исключительной ситуации, а значение может быть передано в блок обработки исключительных ситуаций. Этот механизм, заявленный как стандартный, представляется весьма экзотическим без использования механизма классов. Лишь использование стандартных классов-исключений или разработка собственных классов позволяют в полной мере оценить все возможности такого подхода.

Слайд 15

6. Исключения

Ю.И. Воротницкий. Программирование

Полный формат защищенного блока имеет вид
try {операторызащищенногоблока}
{catch-блоки}…
Catch-блок имеет

6. Исключения Ю.И. Воротницкий. Программирование Полный формат защищенного блока имеет вид try
один из следующих форматов:
catch (тип) {обработчикошибочнойситуации}
catch (тип идентификатор) {обработчикошибочнойситуации}
catch (…) {обработчикошибочнойситуации}
Первый формат используется, если нам надо указать тип перехватываемого исключения, но не нужно обрабатывать связанное с этим исключением значение (это достигается при использовании второго формата оператора catch).
Наконец, третий формат оператора catch позволяет обработать все исключения (в том числе и ошибки выполнения, что было описано в предыдущем пункте).

Слайд 16

6. Исключения

Ю.И. Воротницкий. Программирование

Обработка исключений, возбужденных оператором throw, идет по следующей

6. Исключения Ю.И. Воротницкий. Программирование Обработка исключений, возбужденных оператором throw, идет по
схеме:
1. Создается статическая переменная со значением, заданным в операторе throw. Она будет существовать до тех пор, пока исключение не будет обработано. Если переменная-исключение является объектом класса, при ее создании работает конструктор копирования.
2. Завершается выполнение защищенного try-блока: раскручивается стек подпрограмм, вызываются деструкторы для тех объектов, время жизни которых истекает и т.д.
3. Выполняется поиск первого из catch-блоков, который пригоден для обработки созданного исключения. Поиск ведется по следующим критериям:
если тип, указанный в catch-блоке, совпадает с типом созданного исключения, или является ссылкой на этот тип;
класс, заданный в catch-блоке, является предком класса, заданного в throw, и наследование выполнялось с ключом доступа public;
указатель, заданный в операторе throw, может быть преобразован по стандартным правилам к указателю, заданному в catch-блоке.
в операторе throw задано многоточие.

Слайд 17

6. Исключения

Ю.И. Воротницкий. Программирование
Если нужный обработчик найден, то ему передается управление

6. Исключения Ю.И. Воротницкий. Программирование Если нужный обработчик найден, то ему передается
и, при необходимости, значение оператора throw. Оставшиеся catch-блоки, относящиеся к защищенному блоку, в котором было создано исключение, игнорируются.
Из указанных правил поиска следует, что очень важен порядок расположения catch-блоков. Так, блок catch(…) должен стоять последним в списке, а блок catch (void *) – после всех блоков с указательными типами.
Если ни один из catch-блоков, указанных после защищенного блока, не сработал, по таким же правилам проводится выход из внешнего блока try (если он, конечно, есть!).
В конце оператора catch может стоять оператор throw без параметров. В этом случае работа catch-блока считается незавершенной, и происходит поиск соответствующего обработчика на более высоких уровнях.

Слайд 18

6. Исключения

Ю.И. Воротницкий. Программирование

Пример:
try {

try {

throw ”Error!”;

6. Исключения Ю.И. Воротницкий. Программирование Пример: try { … try { …

} //внутренний try
catch (int) {…
}
catch (float) {…
}

} //внешний try
catch (char * c) {…
}
catch (...) { …
}

Слайд 19

6. Исключения

Ю.И. Воротницкий. Программирование

Пример:
try {

try {

throw ”Error!”;

6. Исключения Ю.И. Воротницкий. Программирование Пример: try { … try { …

} //внутренний try
catch (char *) {…
}
catch (float) {…
}

} //внешний try
catch (char * c) {…
}
catch (...) { …
}

Слайд 20

6. Исключения

Ю.И. Воротницкий. Программирование

Пример:
try {

try {

throw ”Error!”;

6. Исключения Ю.И. Воротницкий. Программирование Пример: try { … try { …

} //внутренний try
catch (char *) {…
}
catch (float) {…
}

} //внешний try
catch (char * c) {…
}
catch (...) { …
}

Слайд 21

6. Исключения

Ю.И. Воротницкий. Программирование

class TMyException {
char* msg;
void operator =

6. Исключения Ю.И. Воротницкий. Программирование class TMyException { char* msg; void operator
(const TMyException& e) {}
public:
TMyException(const char* str) {
assert(str != NULL);
msg = new char[strlen(str) + 1];
strcpy(msg, str);
}
TMyException(const TMyException& e) {
msg = new char [strlen(e.msg) + 1];
strcpy(msg, e.msg);
}
const char* getMessage() const { return msg; }
~TMyException() { delete [] msg; }
};