如果您通过引用捕获异常,是否可以修改它并重新抛出?

时间:2011-12-12 21:30:58

标签: c++ exception exception-handling

标准是否有任何关于引用捕获的异常以及尝试修改它的情况的说法?

请考虑以下代码:

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 引用捕获。

2 个答案:

答案 0 :(得分:20)

异常会改变。

§15.3[except.handle] / 17:

  

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

     

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

因此,如果在my_exception之外发现MyFunc,我们会在callstack中看到"MyFunc"条目(例如http://ideone.com/5ytqN

答案 1 :(得分:10)

是的,你可以这样做。

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