Я знаю, что наличие глобальных переменных не приветствуется. Но в книге Бьярна Страуструпа «Язык программирования C ++» Автор говорит, что «Единственный способ получить контроль в случае выброса из инициализатора нелокального статического объекта — это set_unexpected ()». Как это сделать?
Я разместил вопрос на некоторых других форумах и получил несколько ответов.
Сначала нужно было объявить указатель вместо объекта и инициализировать его в 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()
{
}
Программа выводит сообщение: «Завершить вызов» и завершает работу.
try/catch
блок находится внутри или вместе с областью действия функции. Таким образом, глобальные объекты не могут находиться внутри try/catch
сфера, так что вы может никогда ловить эти исключения.
Вы можете исследовать специальные try/catch
синтаксис:
class Test {
public:
Test ()
try { throw 0; }
catch(...) {}
};
Это обеспечивает некоторое облегчение при обработке таких исключений. Вот одна нить обсуждая то же самое.
Однако вы должны предоставить такой синтаксис для каждого класса, для которого вы объявляете глобальные объекты.
Вам может быть интересно, какая разница, если вы положите try/catch
внутри самого конструктора? Хорошо, если глобальный объект не удается инициализировать, то внутренний try/catch
будет молча абсорбировать это, что плохо.
Но приведенный выше синтаксис даст вам шанс для диагностики ошибок, а затем снова сбросить исключение, которое завершит программу.
Смотрите эту тему Больше подробностей.
С другой стороны, std::unexpected()
называется, когда нет подходящего catch()
за брошенное исключение. Эта функция является стандартной, но вы можете настроить свою собственную с помощью std::set_unexpected()
.