Исключения

Содержание

Слайд 2

Nortel Networks Confidential

Исключения (exception)

Генерация сообщения об ошибке (throw)
Перехват этих сообщений (catch)
В программе

Nortel Networks Confidential Исключения (exception) Генерация сообщения об ошибке (throw) Перехват этих
может одновременно существовать только одно исключение.

Слайд 3

Nortel Networks Confidential

throw и catch

class Stack {
public:
Stack(int size);
void push(char c);

Nortel Networks Confidential throw и catch class Stack { public: Stack(int size);
//...
};
class Overflow {};
class WrongSize {
public:
int wsize;
Wrong_size(int i):
wsize(i) {}
};

void Stack::push(char c) {
if (top storage[top++] = c;
else
throw Overflow();
}

void f() {
try {
Stack s(10);
s.push(‘a’);
} catch (Overflow ex)
{
cerr << “Stack overflow”;
}
}

Слайд 4

Nortel Networks Confidential

Выбор исключений

void f(unsigned int size)
{
try {
Stack s(size);
s.push(‘a’);

Nortel Networks Confidential Выбор исключений void f(unsigned int size) { try {
char c = s.pop();
char d = s.pop();
}
catch (WrongSize ws) {
cerr << “Wrong size:” << ws.wsize;
}
catch (Overflow) { /*...*/
}
catch (Underflow) { /*...*/
}
}

char Stack::pop()
{
if (top==0)
throw Underflow();
return storage[--top];
}

Stack::Stack(int size)
{
if ( size > 10000) {
throw WrongSize(size);
} //...
}

Слайд 5

Nortel Networks Confidential

Группировка исключений

class Exception {};
class StackError: public Exception {};
class Overflow: public

Nortel Networks Confidential Группировка исключений class Exception {}; class StackError: public Exception
StackError {};
class Underflow: public StackError {};
class WrongSize: public StackError {};

try {
Stack s(size);
// ...
}
catch (WrongSize size_exc) {
// process wronsize exception
}
catch (StackError) {
// general processing
}

Слайд 6

Nortel Networks Confidential

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

try {
//...
}
catch (StackError& se) {
// process Stack

Nortel Networks Confidential Перехват исключений try { //... } catch (StackError& se)
Error
}
catch (RuntimeError& ps) {
// process Runtime Error
}
catch (Exception) {
// process Any Internal Exception
}
catch (...) {
// process any other exception
}

Слайд 7

Nortel Networks Confidential

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

try {
//...
}
catch (...) {
// Все исключения

Nortel Networks Confidential Перехват исключений 2 try { //... } catch (...)
перехватываются
// здесь
}
catch (Exception* ex) {
// process Any Internal Exception
}
catch (RuntimeError* re) {
// process Runtime Error
}
catch (StackError* se) {
// process Stack Error
}

Слайд 8

Nortel Networks Confidential

Повторная генерация

void f()
{
try {
// ...
throw Underflow();
}

Nortel Networks Confidential Повторная генерация void f() { try { // ...
catch (RuntimeError& re) {
if ( can_handle_it_completely(re) ) {
// process the exception here
return;
}
else {
do_what_you_can_do(re);
throw;
}
}
}

Слайд 9

Nortel Networks Confidential

Повторная генерация 2

void g()
{
try {
f();
}
catch (StackError&

Nortel Networks Confidential Повторная генерация 2 void g() { try { f();
re) {
// process stack error
}
catch (FileError& re) {
// process file error
}
}

Слайд 10

Nortel Networks Confidential

Исключения в конструкторах

Классические подходы:
Возвратить объект в «неправильном» состоянии
Присвоить значение глобальной

Nortel Networks Confidential Исключения в конструкторах Классические подходы: Возвратить объект в «неправильном»
переменной
Использовать функцию инициализации
Осуществлять инициализацию при первом вызове функции-члена

Слайд 11

Nortel Networks Confidential

Исключения в конструкторах

Stack::Stack(int i)
{
if ( (i < MIN_SIZE) ||

Nortel Networks Confidential Исключения в конструкторах Stack::Stack(int i) { if ( (i
(i > MAX_SIZE) )
{
throw WrongSize(i);
}
//...
}

Stack* get_stack(int size)
{
try {
Stack* s = new Stack(size);
//...
return s;
}
catch (WrongSize) {
// handle bad stack size
}
}

Объект не создан, пока не завершится выполнение его конструктора

Слайд 12

Nortel Networks Confidential

Исключения и инициализация членов

Schedule::Schedule(int i, Date d)
try
: m_stack(i),
m_date(d)
{

Nortel Networks Confidential Исключения и инициализация членов Schedule::Schedule(int i, Date d) try
// constructor
}
catch (Stack::Bad_Size) {
// handle bad size of the stack member
}
catch (Date::Bad_Date) {
// handle bad date of the date member
}

Слайд 13

Nortel Networks Confidential

Исключения и копирование

Копирующий конструктор подобен другим конструкторам:
может генерировать исключения
при этом

Nortel Networks Confidential Исключения и копирование Копирующий конструктор подобен другим конструкторам: может
объект не создается
Копирующее присваивание перед генерацией исключения должно убедиться, что оба операнда находятся в корректном состоянии

Слайд 14

Nortel Networks Confidential

Исключения в деструкторах

Нормальный вызов деструктора
Вызов в процессе обработки исключения
Во 2ом

Nortel Networks Confidential Исключения в деструкторах Нормальный вызов деструктора Вызов в процессе
случае исключение не должно покинуть деструктор (uncaught_exception())
Если все таки покинет вызывается std::terminate()
Т.е. если собираетесь бросить исключения в деструкторе, всегда пользуйтесь uncaught_exception() для проверки на уже существующее исключение.

typedef void (*terminate_handler) ();
terminate_handler set_terminate(terminate_handler);