Как я могу поймать исключения, сгенерированные из конструктора глобального экземпляра класса?

Я знаю, что наличие глобальных переменных не приветствуется. Но в книге Бьярна Страуструпа «Язык программирования C ++» Автор говорит, что «Единственный способ получить контроль в случае выброса из инициализатора нелокального статического объекта — это set_unexpected ()». Как это сделать?

13

Решение

Я разместил вопрос на некоторых других форумах и получил несколько ответов.

Сначала нужно было объявить указатель вместо объекта и инициализировать его в main ()

Второй — извлечь класс (конструктор которого вызывает исключение) из другого класса, который выполняет set_terminate, чтобы установить значимый обработчик. Второй, похоже, прекрасно работает в кодовых блоках ide.

Код, который я использовал для проверки, это:

void f()        //Unexpected exception handler
{
cout<<"Terminate called "<<endl;
exit (0);
}
class A         //Base class that performs set_unexpected
{
terminate_handler h;
public:
A()
{
h=set_terminate(f);
}
~A()
{
set_terminate(h);
}
};
class B:public A    //Derived class that throws unexpected_exception
{
public:
B()
{
throw 1;
}
};
B b;
int main()
{
}

Программа выводит сообщение: «Завершить вызов» и завершает работу.

7

Другие решения

try/catch блок находится внутри или вместе с областью действия функции. Таким образом, глобальные объекты не могут находиться внутри try/catch сфера, так что вы может никогда ловить эти исключения.

Вы можете исследовать специальные try/catch синтаксис:

class Test {
public:
Test ()
try { throw 0; }
catch(...) {}
};

Это обеспечивает некоторое облегчение при обработке таких исключений. Вот одна нить обсуждая то же самое.
Однако вы должны предоставить такой синтаксис для каждого класса, для которого вы объявляете глобальные объекты.

Вам может быть интересно, какая разница, если вы положите try/catch внутри самого конструктора? Хорошо, если глобальный объект не удается инициализировать, то внутренний try/catch будет молча абсорбировать это, что плохо.
Но приведенный выше синтаксис даст вам шанс для диагностики ошибок, а затем снова сбросить исключение, которое завершит программу.
Смотрите эту тему Больше подробностей.

С другой стороны, std::unexpected() называется, когда нет подходящего catch() за брошенное исключение. Эта функция является стандартной, но вы можете настроить свою собственную с помощью std::set_unexpected().

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector