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

13.2.2 Тип виключення та конструктор копії

Якщо конструктор копії викинутого об’єкта в точці викиду недоступний, генерується повідомлення про помилку. Не можна викинути тип чи вказівник на тип , що не має public-конструктора копіювання( якщо тільки функція, що викидає виключеня, не є дружньою).

Приклад:

class TCopCon

{public:

TCopCon();

protected:

TCopCon(const TCopCon&);

friend void funcB(void);

};

void funcA(void)

{ if(щось не впорядку)

{ TCopCon np;

throw np;//повідомлення про помилку: TCopCon::TCopCon(const

//TCopCon&) is not accessible in function funcA()

}

//...

}

void funcB(void)

{ if(щось не впорядку)

{ TCopCon np;

throw np;// все нормально

}

//...

}

13.2.3 Пошук відповідного типу виключення

Після того, як виключення вже викинуто, процедури виконуючої бібліотеки С++ шукають відповідний обробник. Обробник вважається знайденим, якщо:

  • Тип викинутого об’єкта точно співпадає з типом, який заданий в обробнику. Іншими словами, якщо викидається Т, то йому відповідає обробник, який перехоплює T,const T,T& чи const T&.

  • Тип обробника є public-базовим класом викинутого об’єкта

  • обробник чекає вказівник і викинутий об’єкт є вказівником, який може бути перетворений до типу обробника за стандартними правилами перетворення вказівників.

Необхідно пам’ятати, що послідовність слідування обробників є суттєвою. Обробник, який чекає виключення базового класу, автоматично ховає обробник похідного класа:

#include<iostream.h>

class Base{};

class Derived:public Base

{};

void funcA()

{Derived d;

throw d;}

void funcb()

{

throw “помилка в funcB()”;}

int main(void)

{ try{

funcA();}

catch(Base &)

{cout<<“перехоплений Base&”<<endl;}

catch(Derived&)

{cout<<“перехоплений Derived&”<<endl;}

При такій послідовності обробник Derived& ніколи не зможе отримати управління. Треба навпаки. Аналогічно в наступному прикладі:

try{

funcB();}

catch(void*)

{cout<<“перехоплений void*”<<endl;}

catch(const char*)

{cout<<“перехоплений const char*”<<endl;}

return 0;

}

13.2.4 Використання terminate() та некеровані виключення

Якщо для деякого виключення не знайдено відповідного обробника, викликається функція terminate(), яка в свою чергу викликає функцію abort(), що аварійно завершує біжучий процес. Можна встановити свою власну функцію завершення за допомогою функції set_terminate, визначеної в файлі exept.h:

typedef void(_RTLENTRY *terminate_function)()

//...

terminate_function _RTLENTRY set_terminate(terminate_function);

Ця функція повертає адресу попередньої функції завершення. Нова функція завершення не повинна повертати управління коду, який її викликає чи викидає виключення.

Функція завершення викликається також і в тому випадку, коли виключення викидається при виконанні деструктора - якщо деструктор викликався в процесі розмотуванні стека, який був ініційований раніше викинутим виключенням.