【问题标题】:If you catch an exception by reference, can you modify it and rethrow?如果通过引用捕获异常,是否可以修改并重新抛出?
【发布时间】:2011-12-12 21:30:57
【问题描述】:

对于通过引用捕获的异常以及修改它的尝试会发生什么,该标准是否有任何规定?

考虑以下代码:

class my_exception: public std::logic_error
{
public:
    std::vector<std::string> callstack;
};

void MyFunc()
{
    try
    {
        SomethingThatThrows();
    }
    catch (my_exception & e)
    {
        e.callstack.push_back("MyFunc");
        throw;
    }
}

这是一个人为的例子,我实际上并没有尝试这样的事情。我只是好奇会发生什么,基于另一个线程中的建议,即 const 引用应该捕获异常。

【问题讨论】:

  • boost::exception 为此提供了一些简洁的工具。
  • push_back 可以抛出。字符串的复制构造函数可以抛出。今天我更喜欢 std::array what_msg 里面的异常。这样您就可以轻松实现虚拟化。

标签: c++ exception exception-handling


【解决方案1】:

异常会改变。

§15.3[except.handle]/17:

当处理程序声明一个非常量对象时,对该对象的任何更改都不会影响临时对象 通过执行 throw 表达式初始化的对象。

当处理程序声明一个对 一个非常量对象,对引用对象的任何更改都是对初始化的临时对象的更改 当 throw 表达式被执行时,如果该对象被重新抛出,它将生效。

所以如果my_exceptionMyFunc 之外被捕获,我们将在调用堆栈中看到"MyFunc" 条目(例如http://ideone.com/5ytqN

【讨论】:

    【解决方案2】:

    是的,你可以这样做。

    当您使用throw; 重新抛出当前异常时,不会复制:原始临时异常对象将被重新抛出。因此,您在处理程序中对该对象所做的任何更改都将在您下次捕获时出现在异常对象中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-02-13
      • 1970-01-01
      • 1970-01-01
      • 2013-10-04
      • 2018-12-17
      • 1970-01-01
      • 2010-10-03
      相关资源
      最近更新 更多