为什么要将异常作为引用引用到const?

cai*_*rol 74 c++ const exception

我已经多次听过和读过,最好将异常作为引用而不是引用来引用.为什么是

try {
    // stuff
} catch (const std::exception& e) {
    // stuff
}
Run Code Online (Sandbox Code Playgroud)

比...更好

try {
    // stuff
} catch (std::exception& e) {
    // stuff
}
Run Code Online (Sandbox Code Playgroud)

Kor*_*icz 56

你需要:

  • 引用,以便您可以多态地访问异常
  • 一个const来提高性能,并告诉编译器你不会修改对象

后者并不前者那么重要,但是删除const的唯一真正原因是表示你想要对异常进行更改(通常只有在想要通过添加上下文重新抛出更高级别时才有用) .

  • `一个增加性能的const`怎么样? (20认同)
  • 看看由apple clang 7和gcc 5(优化O3)生成的程序集,我没有看到const ref和非const ref程序集之间有任何区别.所以,我猜gcc和apple clang的优化没有区别 (10认同)
  • @mango大概是指能够调用虚函数(例如`std :: exception`的`what()`函数).如果按值捕获,则无法调用该函数并获取原始异常详细信息. (3认同)
  • “多态访问异常”是什么意思? (2认同)
  • 编译器可以轻松查看您修改的对象和不修改的对象([SSA](https://en.wikipedia.org/wiki/Static_single_assignment_form)和常量传播).需要更好的解释(或者它是一个神话?). (2认同)
  • const 在这里(以及在任何合理设计的程序中)与性能无关! (2认同)

Lig*_*ica 29

根本没有理由.

异常对象存在于自己的内存空间中因此您不必担心捕获在临时表达式中创建的异常.

您所做的一切都是承诺您不会修改异常对象,但由于异常对象应该具有不可变的接口,因此这里没有什么实用的.

但是,当你阅读它时,它可能会让你感到温暖和舒适 - 这对我来说就是这样!

他们有自己的,特殊的线程局部堆栈.
免责声明: Boost.Exception打破了这一点,以便做一些时髦的东西,并在构建后添加异常细节.但这是hackery!

  • @RichardDally 检查 *C++ Primer 5th*,§ 18.1.1 Excpetion 对象。它说*异常对象驻留在由编译器管理的空间中,保证可以被调用的任何catch访问。异常处理完成后,异常对象被销毁。* (2认同)

War*_*pin 5

它告诉编译器您不会调用任何修改异常的函数,这可能有助于优化代码.可能没有多大区别,但这样做的成本也很小.