Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ООП.doc
Скачиваний:
77
Добавлен:
07.03.2016
Размер:
1.78 Mб
Скачать

Void f1()

{

// Відкриваємо файл

ifstream ifs("\\INVALID\\FILE\\NAME");

if (!ifs)

{

cout << "Генеруємо виключення" << endl;

throw "Помилка при відкритті файлу";

}

}

Void f2()

{

Hello h; // Створюємо локальний об’єкт

f1(); // Викликаємо функцію, яка генерує виключення

}

Void main()

{

try

{

cout<< "Входимо в try-блок" << endl;

f2();

cout << "Виходимо з try-блока" << endl;

}

catch(int i)

{

cout<<"Викликаний обробник int, виключення – " <<i<<endl;

return;

}

catch(const char * p)

{

cout<<"Викликаний обробник const char*, виключення – "

<< p << endl;

return;

}

catch(...)

{

cout << "Викликаний обробник всіх виключень" << endl;

return;

}

}

Результати виконання програми:

Входимо в try-блок

Hello!

Генеруємо виключення

Bye!

Викликаний обробник const char*, виключення – Помилка при відкритті файлу

Зверніть увагу, що після породження виключення був викликаний деструктор локального об'єкту, хоча управління з функції f1 було передане обробникові, що знаходиться у функції main. Повідомлення "Виходимо з try-блоку" не було виведено. Таким чином, механізм виключень дозволяє коректно знищувати об'єкти при виникненні помилкових ситуацій. Тому виділення і звільнення ресурсів корисно оформляти у вигляді класів, конструктор яких виділяє ресурс, а деструктор – звільняє. Як приклад можна привести клас для роботи з файлом. Конструктор класу відкриває файл, а деструктор – закриває. В цьому випадку є гарантія, що при виникненні помилки файл буде коректно закритий, і інформація не буде загублена.

Розглянемо приклад використання виключень при контролі введення даних. Введення має бути цілим числом в діапазоні 0-20:

#include <iostream>

using namespace std;

#include <conio.h>

#include <windows.h>

Void GotoXy(int X, int y)

{

COORD coord = { Y, X };

SetConsoleCursorPosition(

GetStdHandle(STD_OUTPUT_HANDLE), coord);

}

bool IsNumeric(char *str, bool dr )

{

int i,pos = 0;

if (!strlen(str)||str[0] == '.'|| str[0] == ',')

return false ;

for (i = 0; i < (int)strlen(str); i++ )

{

if (str[i] == ',')str[i] = '.';

if (i == 0 && (str[0] == '+' || str[0] == '-'))

continue;

if ((str[i] >= '0' && str[i] <='9') || str[i]=='.')

continue;

return false;

}

for (i = 1; i < (int)strlen(str);i++)

if (str[i]=='.')pos++;

if ( (!dr && pos) || (pos > 1)) return false ;

return true;

}

char* recode(char *txt)

{

static char buf[257];

strcpy(buf,txt);

for(unsigned int i=0;i<strlen(buf);i++)

{

if (buf[i]>='А'&&buf[i]<='п')buf[i]-=64;

if (buf[i]>='р'&&buf[i]<='я')buf[i]-=16;

}

return buf;

}

Void kontr (char* str) throw (const char*)

{

if (!IsNumeric(str, 0))throw

"Введено не ціле число\n";

int a = atoi(str);

if ( a < 0 || a > 20) throw

"Помилка – Діапазон 0 – 20\n";

}

Void main()

{

char k[100];

bool vozv;

while(1)

{

vozv = true;

GotoXY(0,0);

cout << " " ;

GotoXY(0,0);

cout << recode("Введіть значення k =");

cin >> k;

try

{

kontr(k);

}

catch (const char* d)

{

GotoXY(1,0);

cout << recode((char*)d);

vozv = false;

}

if(vozv)break;

} // while

system("cls");

getch();

}

У даному прикладі функція IsNumeric() повертає true тільки при введенні цілого числа, в противному випадку – false. У функції kontr() генеруються текстові виключення при невиконанні контролю значень, що вводяться. Слід зазначити, що використання виключень при контролі введення не є кращим варіантом. Приклад наводиться для практики використання виключень.

Розглянемо приклад обробки виключень класу:

#include <iostream>

using namespace std ;

char* recode(char *txt)

{

static char buf[257];

strcpy(buf,txt);

for(unsigned int i=0;i<strlen(buf);i++)

{

if (buf[i]>='А'&&buf[i]<='п')buf[i]-=64;

if (buf[i]>='р'&&buf[i]<='я')buf[i]-=16;

}

return buf;

}

class CTest

{

public:

CTest(){};

~CTest(){};

char *Show()

{return recode("Виключення у класі CTest class");}

};

class CDtorDemo

{

public:

CDtorDemo();

~CDtorDemo();

};

CDtorDemo::CDtorDemo()

{

cout << recode("Конструктор") << endl;

}

CDtorDemo::~CDtorDemo()

{

cout << recode("Деструктор") << endl;

}