【问题标题】:Why catch an exception as reference-to-const?为什么要捕获异常作为对 const 的引用?
【发布时间】:2011-01-09 20:24:18
【问题描述】:

我多次听到并阅读到,最好将异常捕获为对 const 的引用,而不是作为引用。为什么是:

try {
    // stuff
} catch (const std::exception& e) {
    // stuff
}

优于:

try {
    // stuff
} catch (std::exception& e) {
    // stuff
}

【问题讨论】:

    标签: c++ exception constants


    【解决方案1】:

    你需要:

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

    后者没有前者那么重要,但删除 const 的唯一真正原因是表明您想要对异常进行更改(通常只有在您想要将其与添加的上下文重新抛出到更高的级别)。

    【讨论】:

    • “告诉编译器你不会修改对象”——我想如果你将对象作为参数传递给函数调用,这可能会很有用。
    • “以多态方式访问异常”是什么意思?
    • @mango 大概意思是可以调用一个虚函数(比如std::exceptionwhat()函数)。如果按值捕获,则无法调用该函数并获取原始异常详细信息。
    • 查看了由 apple clang 7 和 gcc 5(优化 O3)生成的程序集,我看不出 const ref 和非 const ref 程序集之间有任何区别。所以,我想 gcc 和 apple clang 的优化没有区别
    • 编译器可以很容易地看到您修改了哪些对象,哪些没有修改(SSA 和常量传播)。需要更好的解释(或者这是一个神话?)。
    【解决方案2】:

    基本上没有任何理由。

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

    你所做的只是保证你不会修改异常对象,但是由于异常对象应该有一个不可变的接口,所以这里真的没有什么实用的。

    然而,它可能会让你在阅读时感到温暖和舒适——这就是我的感觉!

    他们有自己的特殊线程本地堆栈。
    免责声明: Boost.Exception 打破了这一点,以便做一些时髦的事情并在构建后添加异常细节。但这是骇人听闻的!

    【讨论】:

    • 能否详细说明Exception objects live in their own memory space ?你有什么好的建议吗?
    • @LeFlou:我可以为您指出标准,但认为“一本好书”会有点误导......:P
    • 绝对是的,从标准的角度了解更多信息会很有趣。我在看Technical Report on C++ Performance,你有更相关的文件吗?
    • @LeFlou:嗯,没有比标准本身更权威的了......
    • @RichardDally 检查C++ Primer 5th,§ 18.1.1 Excpetion 对象。它说 异常对象驻留在空间中,由编译器管理,保证可以被调用的任何 catch 访问。异常处理完毕后,异常对象被销毁。
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      你要修改异常吗?如果不是,它也可能是 const。您应该在其他任何地方使用 const 的原因相同(我说应该是因为它在表面上并没有太大的区别,可能有助于编译器,也有助于编码人员正确使用您的代码,而不是做他们不应该做的事情)

      异常处理程序,可能是特定于平台的,并且可能将异常放在有趣的地方,因为它们不希望它们发生变化?

      【讨论】:

        【解决方案5】:

        出于同样的原因,您使用 const。

        【讨论】:

        • 出于同样的原因,为什么更喜欢引用而不是指针:-)
        • 简单易懂,但不是真正的答案。
        猜你喜欢
        • 2017-06-19
        • 2020-04-11
        • 2015-07-18
        • 1970-01-01
        • 1970-01-01
        • 2012-08-27
        • 2019-11-20
        • 2021-12-26
        • 1970-01-01
        相关资源
        最近更新 更多