Знакомство с исключительными ситуациями начнем с примера:
#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(...), данное объявление говорит о том, что ловить надо все исключительные ситуации.