Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

ООП C++_9

.pdf
Скачиваний:
46
Добавлен:
10.02.2015
Размер:
340.67 Кб
Скачать

ООП 2013

Глава 9.

Исключения

МГТУ им. Н.Э. Баумана Факультет Информатика и системы управления

Кафедра Компьютерные системы и сети Лектор: д.т.н., проф.

Иванова Галина Сергеевна

1

9.1 Механизм исключений С++

Механизм исключений предполагает автоматическое формирование специального блока информации при обнаружении аварийной ситуации.

Традиционный подход:

Механизм исключений:

if (p!=NULL) *p=3;

__try {*p=3;}

else <Действие по устранению

__except (<Фильтр>)

ошибки>

{ Действия по устранению ошибки}

Достоинство: позволяет группировать обработку ошибок в том месте, где возможно принятие решения об ее устранении:

Объект A

Объект B

__try

?

...

 

__except

 

2

Генерация исключений С++

В языках С и С++ используются разные стандарты обработки исключений.

Генерация исключений:

throw [<Тип>](<Аргументы>);

где <Тип> – тип или класс генерируемого значения; если тип не указан, то компилятор определяет его исходя из типа аргумента (обычно это один из встроенных типов);

<Аргументы> – одно или несколько выражений, значения которых будут использованы для инициализации генерируемого объекта.

Примеры:

а) throw (”Неверный параметр”); /* тип const char * с указанным

б)

throw

 

в кавычках значением */

(221); // тип const int с указанным значением

в)

class

E { //класс исключения

 

public: int num;

// номер исключения

 

 

E(int n): num(n){}

// конструктор класса

};

 

throw E(5); // тип исключения – класс E, значение – 5

3

 

Перехват и обработка исключений

try {<Защищенный код>}

catch (<Ссылка на тип>){<Обработка исключений>} При этом выполняются следующие правила:

1)исключение типа T будет перехватываться обработчиками типов T, const T, T& или const T&;

2)обработчики типа базового класса перехватывают исключения типа производных классов;

3)обработчики типа void* перехватывают все исключения типа указателя.

Блок catch, для которого в качестве типа указано «…» обрабатывает исключения всех типов.

Примеры:

try {<Операторы>} // выполняемый фрагмент программы catch (EConvert& A){<Операторы>} /* перехват исключений

типа EConvert */

catch (char* Mes){<Операторы>} //перехват исключений char* catch(…) {<Операторы>} //перехват остальных исключений4

Возобновление исключения

Если перехваченное исключение не может быть обработано, то оно

возобновляется.

 

Пример:

 

class E{};

// класс исключения

void somefunc()

 

{ if(<условие> throw Out(); }// генерация исключения void func()

{try { somefunc(true); }

catch(E& e){ if (<условие>) throw; } /* если здесь

исключение обработать нельзя, то возобновляем его */ } void mainfunc()

{try { func();}

catch(E& e){ … } } // здесь обрабатываем исключение

5

Доступ к аргументам исключения

Использование имени переменной в качестве параметра оператора catch позволяет операторам обработки получить доступ к аргументам исключения через указанное имя.

Пример:

 

 

class E //класс исключения

 

{ public: int num;

// номер исключения

E(int n): num(n){}

// конструктор

}

 

 

 

 

try { ...

 

 

throw E(5);

// генерируемое исключение

...}

 

 

catch (E& e){if (e.num==5) {…}} // получен доступ к полю

6

Последовательность обработки исключения

при генерации исключения происходит конструирование временного объекта исключения;

выполняется поиск обработчика исключения;

при нахождении обработчика создается копия объекта с указанным именем;

уничтожается временный объект исключения;

выполняется обработка исключения;

уничтожается копия исключения с указанным именем.

Поскольку обработчику передается копия объекта исключения, желательно в классе исключения с динамическими полями предусмотреть копирующий конструктор и деструктор.

7

Обработка объекта исключения (Ex9_1)

#include <conio.h>

 

#include <stdio.h>

 

class MyException

 

{ protected: int nError;

 

public: MyException(int nErr) {nError=nErr;}

~MyException(){puts("destructor");}

void ErrorPut(){printf("Error %d.\n",nError);}

};

destructor

int main(int argc, char* argv[])

Error 5.

{

destructor

try

destructor

{

program

throw MyException(5);

Press any key to continue

}

 

catch(MyException E){E.ErrorPut();}

puts("program");

 

getch(); return 0;

8

}

 

Спецификация исключений

При объявлении функции можно указать, какие исключения она может генерировать:

throw(<тип>,<тип>…).

Пример:

void func() throw(char*,int){…} /*функция может генерировать исключения char* и int */

Спецификация исключений не считается частью типа функции и, следовательно, ее можно изменить при переопределении:

class ALPHA

{public: struct ALPHA_ERR{};

virtual void vfunc() throw(ALPHA_ERR){}

};

class BETA : public ALPHA { public:

void vfunc() throw(char *) {}

};

9

 

Уничтожение локальных переменных при обработке исключения (Ex9_2)

#include <iostream>

При «раскручивании» стека

 

using namespace std;

локальные переменные

 

void MyFunc( void );

уничтожаются

 

class CTest

 

 

{public: CTest(){};

 

 

 

~CTest(){};

 

 

 

const char *ShowReason() const

 

};

{ return "Exception in CTest class."; }

 

 

 

 

class CDtorDemo

 

 

{public: CDtorDemo();

 

 

};

~CDtorDemo();

 

 

 

 

 

CDtorDemo::CDtorDemo()

 

 

{

cout << "Constructing CDtorDemo." << endl;}

 

CDtorDemo::~CDtorDemo()

 

 

{

cout << "Destructing CDtorDemo." << endl;}

10

 

 

 

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]