Подтвердить что ты не робот

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

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

4b9b3361

Ответ 1

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

Сначала нужно было объявить указатель вместо того, чтобы иметь объект и инициализировать его в 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()
{
}

В программе отображается сообщение: "Завершить вызов" и выйдет.

Ответ 2

Блок

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

Вы можете изучить специальный синтаксис try/catch:

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

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

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

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