异常类复制构造函数

时间:2018-06-15 23:02:12

标签: c++ c++14 custom-exceptions

通过使用用于抛出,抛出的类的复制构造函数,我正在测试堆栈展开调用std::terminate时的抛出方式。

Per C ++ 14 N4296 - §15.1.3:

  

抛出异常copy-initializes(8.5,12.8)一个临时对象,   称为异常对象。临时是一个左值,习惯了   初始化匹配处理程序中声明的变量(15.3)。

class X
{
  public:

    X() = default;

    X(const X&)
    {
      throw std::runtime_error{"X copy constructor"};
    }
};

int main()
{
  try
  {
    throw X{};
  }
  catch(const std::exception& e)
  {
    std::cout << e.what() << std::endl; // this line gets executed, does not terminate
  }
  catch(const X& other)
  {
    std::cout << "X exception" << std::endl;
  }
}

上面的代码怎么不调用std::terminate?我对上面的代码的理解是throw X{}中的try启动堆栈循环,然后调用复制构造函数来调用处理程序,但复制构造函数也会抛出。作为注释,如果更改throw X{}的复制构造函数的throw表达式,则它将终止。

1 个答案:

答案 0 :(得分:4)

在初始化异常对象之前,尚未抛出任何异常。因此,系统尚未开始进行异常处理。

由于副本正在抛出,并且初始化异常对象的原因是,成功执行的唯一throw是复制构造函数中的那个。

  

作为注释,如果更改复制构造函数的throw X {}的throw表达式,则它会终止。

由于无限递归,它实际上是一个堆栈溢出。每次构建异常对象的尝试都会引发另一个异常,并引发另一个构造异常对象的尝试。