C++ Программирование в среде С++ Builder 5

         

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


Если не удается найти подходящий обработчик исключения в списке текущего пробного блока, происходит переход на более высокий уровень, т. е. к списку обработчиков try-блока, -непосредственно включающего текущий. Если такой, конечно, имеется.

Если обработчика для данного исключения в программе не находится вообще, оно считается неуправляемым. В этом случае вызывается функция terminate () . Она, в свою очередь, вызывает функцию abort () , которая аварийно завершает программу.

Можно установить свою собственную процедуру завершения с помощью функции set_terminate () ; прототип ее находится в except, h:

typedef void(_RTLENTRY *terminate_function) ();

terminate_function _RTLENTRY set_terminate(terminate function);

Как и другие подобные функции, она возвращает адрес предыдущей процедуры завершения. Процедура завершения не может ни возвратить управление, ни выбросить исключение.

Следующая программа демонстрирует некоторые моменты вышесказанного. Ее вывод показан на рис. 12.2.

Листинг 12.3. Поиск обработчиков и неуправляемые исключения

///////////////////////////////////////////////////////////

//Unhandled. срр: Прохдедура для неуправляемых исключений.

//

#include <iostream.h>

#include <except.h>

#pragma hdrstop



#include <condefs.h>

class Dummy {}; // Пустой класс исключения.

void FuncB(int f) {

if (!f) { cout << "FuncB: throwing int..." << endl;

throw 7;

} else {

cout<< "FuncB: throwing char*..."<< endl;

throw "Exception!";

} }

void FuncA(int f)

{

try {

FuncB(f);

} catch(char* str) { // Обработчик выбрасывает Dummy.

cout << "FuncA: char* caught. Rethrowing Dummy..."<< endl;

Dummy d;

throw d;

} }

void MyTerminate() // Новая процедура завершения. {

cout << "Termination handler called..." << endl;

abort ();

}

int main() {

set_terminate(MyTerminate); // Установка процедуры

// завершения.

for (int j=0; j<2; j++) { try {

FuncA(j) ;

} catch(int k) {

cout << "Main: int caught - " << k << endl;

} }

// Следующие операторы исполняться не будут... cout “ "Exiting main..." “ endl;

return 0;

}

Рис.12.2 Выполнение программы Unhandled

Тело пробного блока в main () выполняется два раза. Имеется вложенный пробный блок в FuncA () . На первом проходе FuncB () выбрасывает int, для которого нет обработчика во внутреннем блоке и потому перехватываемое во внешнем пробном блоке, т. е. в main О . На втором проходе выбрасывается строка, которая перехватывается в FuncA () . Обработчик сам выбрасывает исключение Dummy — неуправляемое, поэтому вызывается установленная пользователем процедура завершения.



Содержание раздела