【问题标题】:Are std::exception objects created when an exception is thrown?抛出异常时是否创建了 std::exception 对象?
【发布时间】:2014-04-23 16:40:25
【问题描述】:

我有一个类CustomException,它实现了std::exception,我在其中明确删除了复制和移动构造函数。当我抛出该类的异常时,调用已删除的构造函数时会出现编译错误。

是否在某处创建了 CustomException 实例?抛出异常时会创建哪些对象?

【问题讨论】:

    标签: c++ exception c++11 copy-constructor move-constructor


    【解决方案1】:

    在展开堆栈之前,throw 运算符(除了 throw;不带参数,用于重新抛出)在特殊的内存区域中创建一个异常对象。根据情况,对象以不同的方式初始化:构造函数、复制构造函数、移动构造函数 (https://en.cppreference.com/w/cpp/language/copy_elision) 使用提供给 throw 运算符的内容。因此,信息可从异常对象中获得,该对象在完成异常处理之前一直处于活动状态,但提供给 throw 运算符的内容会在堆栈展开时被销毁)。

    在您的情况下,编译器需要您删除的函数来在引发异常时初始化异常对象或初始化 catch-clause 参数,或两者兼而有之 - 因为这是编译器通过设计(使用函数)实现它的方式.

    【讨论】:

      【解决方案2】:

      当你抛出时,会构造一个与 throw 的操作数相同类型的异常对象,但移除了顶级 cv 限定符(如果你抛出一个数组或函数,它们也会衰减到它们对应的指针)。

      所以你所做的恐怕是不行的。

      C++ 标准章节 [except.throw] §5:

      当抛出的对象是类对象时,复制/移动构造函数和析构函数应该是可访问的,即使复制/移动操作被省略(12.8)。

      【讨论】:

      • 当一个异常被线程或异步抛出并且你在初始调用者中得到它时特别需要它。
      猜你喜欢
      • 1970-01-01
      • 2012-04-14
      • 1970-01-01
      • 2012-06-12
      • 1970-01-01
      • 2021-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多