Visual C++ MFC в подробностях
Страница 16. Исключительные ситуации


Исключительные ситуации

Знакомство с исключительными ситуациями начнем с примера:

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

 

 
« Предыдущая статья   Следующая статья »