好吧,我一直在阅读this一篇关于避免异常处理错误的文章,看起来很好,但我坚持要澄清的一点就是说,
抛出异常并且控制从try块传递到 处理程序,C ++运行时调用所有自动对象的析构函数 自try块开始以来构建。
另一点似乎建议在捕获中通过引用抛出对象是一种很好的做法,因为它避免了内存管理和复制,对我来说似乎很奇怪
try
{
Object o;
//make error..
throw ref(o);
}catch(Object & p)
{
//do some handle..
}
与所说的相比,上面的代码是否合适?并不是所有在try中构造的对象在它到达throw时都会解开。或者它会在catch之后展开吗?
答案 0 :(得分:2)
通过引用抛出异常对象是否合适?
没有。它不是。在您的示例中,o
将在throw之后作为堆栈展开的一部分被销毁,因此您将捕获悬空引用。
做什么文章并按价值投掷:throw o;
,throw std::move(o);
(如果o
便宜 - 移动 - 难以复制)或在单独的函数中移动异常调整并执行throw make_error(/*...*/)
之类的操作。这将抛出一个对象o
的副本,它具有单独的生命周期,并且在处理之前不会被堆栈展开破坏。
您应该通过引用(catch Object& o
)捕获异常,以避免额外的异常对象副本和潜在的切片。
所以你应该按值抛出对象(以避免生命周期问题)并通过引用捕获(避免切片和额外复制)