通过引用抛出异常对象是否合适?

时间:2016-08-13 16:39:23

标签: c++ exception-handling

好吧,我一直在阅读this一篇关于避免异常处理错误的文章,看起来很好,但我坚持要澄清的一点就是说,

  

抛出异常并且控制从try块传递到   处理程序,C ++运行时调用所有自动对象的析构函数   自try块开始以来构建。

另一点似乎建议在捕获中通过引用抛出对象是一种很好的做法,因为它避免了内存管理和复制,对我来说似乎很奇怪

try
{

Object o;
//make error..
throw ref(o);
}catch(Object & p)
{
//do some handle..
}

与所说的相比,上面的代码是否合适?并不是所有在try中构造的对象在它到达throw时都会解开。或者它会在catch之后展开吗?

1 个答案:

答案 0 :(得分:2)

  

通过引用抛出异常对象是否合适?

没有。它不是。在您的示例中,o将在throw之后作为堆栈展开的一部分被销毁,因此您将捕获悬空引用。

做什么文章并按价值投掷:throw o;throw std::move(o);(如果o便宜 - 移动 - 难以复制)或在单独的函数中移动异常调整并执行throw make_error(/*...*/)之类的操作。这将抛出一个对象o 的副本,它具有单独的生命周期,并且在处理之前不会被堆栈展开破坏。

您应该通过引用(catch Object& o)捕获异常,以避免额外的异常对象副本和潜在的切片。

所以你应该按值抛出对象(以避免生命周期问题)并通过引用捕获(避免切片和额外复制)