Страница 16 из 51 Исключительные ситуации Знакомство с исключительными ситуациями начнем с примера: #include "iostream.h" #include "afxwin.h"
void funct1(); void funct2(); void funct3();
void main() { try { funct1(); funct2(); funct3(); } catch(CString cs) { cout << "Error Detecting" << endl; cout << cs << endl; } }
void funct1() { }
void funct2() { CString s="Error funct 2"; int x; cin >> x; if (x==1) throw (s); }
void funct3() { }
Создавайте приложение Win32 Console запускайте. Программа попросит ввести Вас число. Если Вы введете 1, то увидите на экране: 1 Error Detecting Error funct 2 Press any key to continue
Итак, в чем суть данного кода. У нас есть комплекс функций, в каждой из которых может произойти ошибка. Вот эти функции мы и защищаем блоком try. Если ошибка произойдет то управление передается в блок catch и сообщается о том, что произошла ошибка. Давайте введем термин исключительная ситуация. Исключительная ситуация - это ситуация в программе требующая специальной обработки. А вот под специальной ситуацией можно понимать разные вещи. Например нельзя открыть файл или ошибка соеднинения. Вопрос этот тонкий, и как мне кажется каждый должен решать сам, что в Вашей программе является исключительной ситуацией. Рассмотрим условный пример. Условный пример. Ваша программа должна установить связь с базой данный используя ODBC. Database db;// объект базы данных db.Open("x.db");// имя файла db.OpenTable("table1");// имя таблицы Как Вы догадываетесь ошибки могут быть в любой момент. Например консруктор может закончиться неудачей. Например не хватило памяти. Или файл не найден, или таблицы нет. Или база данных открыта другой программой в эксклюзивном режиме. Это просто поток возможных ошибок. Выходы из этой ситуации придуманы давно. Заводить переменную как флаг ошибки и обрабатывать её. Вот так например Database db; if (db.Initial()) { db.Open("x.db"); if (db.Open()) { if (db.OpenTable("table1")) { } } }
Но еще ошибку надо проверить на тип, например отсутсвует файл или нет доступа. И всё это в коде функции, обрастая if , case и т.д. не тяжело и потерять смысл, о чем вообще функция :-). Обработка исключительных ситуаций позволяет крассиво решить эту проблемму. Вот так: try { Database db; db.Open("x.db"); db.OpenTable("table1"); } catch(...) { cout << "Error detected " << end; }
Как видите обработка ошибок стекается в одну функцию. Внимание для того чтобы пользоваться этими возможностями функции классы должны быть ориентированны на обработку исключительных ситуаций. Обработка исключительных ситуаций входит в стандарт ANSI C++, и её должны поддерживать компиляторы. Ниже приведен пример, который работает на VC++ 5. #include "iostream.h" #include "afxwin.h"
void main() { try { int x=1; int y=0; x=x/y; cout << " Hello bad cod "; } catch(...) { cout << "Error detecting" << endl; } }
При выполнении этой программы программа не завершится ошибкой Windows, и надпись Hello bad cod Вы не увидите. На экране будет зловещее Error detecting. Но реакция на ошибку в Вашей власти. Итак давайте разберемся с обьявлениями. Защищается блок кода так. try { // защищаемый код } catch(...) { // реакция на ошибку }
Если Вам самом необходимо вызвать исключительную ситуацию Воспользуйтесь throw: // Действие // Если ошибка вызвать throw "Error"
Обработка ошибок и из вызов основаны на классах. В примере ниже вы получите abnormal terminated так как тип возбуждаемой ошибки не соответсвует классу обработки. throw type_error и catch (type_error) должны совпадать. #include "iostream.h" #include "afxwin.h" void main() { try {
throw 23.34; } catch(int i) { cout << "Error detecting" << endl; } }
Для обработки этой ошибки необходимо обьявить catch(double i) В примерах я часто объявлял catch(...), данное объявление говорит о том, что ловить надо все исключительные ситуации. |