在构造函数中引发异常的处理程序是什么?

时间:2014-05-20 06:56:27

标签: c++ c++11 exception-handling try-catch

我是C ++异常处理的新手。我心中的规则是,

  1. 如果在调用链(函数调用堆栈)中找不到异常处理程序,则调用 terminate 函数
  2. 处理程序是 catch {} 块。
  3. 但是,我无法理解以下行为。

    #include <iostream>
    #include <exception>
    using namespace std;
    
    struct X {
      X() try { throw exception(); }
      catch (exception &e) {
        cout << "Exception caught in constructor!" << endl;
      }
    };
    
    int main() {
    
      try {
        throw exception();
      }
      catch (exception &e) {
        cout << "Exception caught in function." << endl;
      }
      cout << "After Exception being caught in function" << endl;
    
      try {
        X x;
      }
      catch (exception &e) {
        cout << "Why exception is caught again!" << endl;
      }
    
      return 0;
    }
    

    输出

    Exception caught in function. After Exception being caught in function Exception caught in constructor! Why exception is caught again!

    问题1:似乎在X的构造函数中抛出的异常被捕获(或。处理)两次。或者为什么构造函数后面的catch {}块不算作构造函数中异常的处理程序?

    如果我没有将X x;放在try{}块中并将其捕获到main()中,则输出为:

    Exception caught in function. After Exception being caught in function Exception caught in constructor! terminate called after throwing an instance of 'std::exception' what(): std::exception Aborted (core dumped)

    问题2:当我们在try块中没有X x;时,是否调用了默认的terminate()函数?

2 个答案:

答案 0 :(得分:4)

使用:

X() try { throw exception(); }
catch (exception &e) {
    cout << "Exception caught in constructor!" << endl;
}

X对象没有完全构造,因此catch不能忽略异常并且应该重新抛出它。

国际海事组织,X有一个成员投掷......(X() try : member(0) {} catch(exception&) {})时更清楚。

请注意,您可以在构造函数块中使用 normal try catch:

X() {
    try { throw exception(); }
    catch (exception &e) {
        cout << "Exception caught in constructor!" << endl;
    }
}

更自然。

答案 1 :(得分:1)

两个例外。

struct X {
  X() try { throw exception(); }
  catch (exception &e) {
    cout << "Exception caught in constructor!" << endl;
  }
};

在异常之后,您将在构造函数中处理它。 但是你没有构建 对象尚未在调用者方面没有任何对象。呼叫者,召集者 应该处理一个未构造的对象情况。

第二个问题,是的。标准中的每 [except.terminate] 。它导致调用std::terminate

相关问题