C++ 为什么捕获异常作为常量的引用?

C++ 为什么捕获异常作为常量的引用?,c++,exception,constants,C++,Exception,Constants,我已经听过很多次了,也读过很多次了,捕捉一个异常作为对const的引用比作为引用更好。原因是: try { // stuff } catch (const std::exception& e) { // stuff } 优于: try { // stuff } catch (std::exception& e) { // stuff } 它告诉编译器,您不会调用任何修改异常的函数,这可能有助于优化代码。可能没有多大区别,但这样做的成本也非常小。

我已经听过很多次了,也读过很多次了,捕捉一个异常作为对const的引用比作为引用更好。原因是:

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

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

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

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

出于与使用常量相同的原因。

出于与使用常量相同的原因。

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


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

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

异常处理程序,可能是特定于平台的,可能会将异常放在有趣的地方,因为它们不希望它们更改?

您需要:

  • 引用,以便您可以多态地访问异常

  • 一个常量来提高性能,并告诉编译器您不打算修改对象
后者不如前者重要,但删除const的唯一真正原因是发出信号,表示您希望对异常进行更改(通常只有在您希望使用添加的上下文将异常重新发送到更高级别时才有用)。

您需要:

  • 引用,以便您可以多态地访问异常

  • 一个常量来提高性能,并告诉编译器您不打算修改对象

后者不如前者重要,但删除const的唯一真正原因是发出信号,表示您希望对异常进行更改(通常只有在您希望使用添加的上下文将异常重新引用到更高级别时才有用)。

基本上没有理由

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

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

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

†它们有自己的特殊线程本地堆栈。

——免责声明:Boost。异常会破坏此功能,以便在构建后执行时髦的操作并添加异常详细信息。但这是黑客

基本上没有理由

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

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

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

†它们有自己的特殊线程本地堆栈。


——免责声明:Boost。异常会破坏此功能,以便在构建后执行时髦的操作并添加异常详细信息。但这是黑客

这与为什么喜欢引用而不是指针的原因相同:-)简单而圆滑,但不是真正的答案。这与为什么喜欢引用而不是指针的原因相同:-)简单而圆滑,但不是真正的答案。“告诉编译器你不打算修改对象”-我想如果您将对象作为参数传递给函数调用,这可能会很有用。您所说的“多态访问异常”是什么意思?@mango可能意味着能够调用虚拟函数(例如
std::exception
what()
函数)。如果按值捕获,则无法调用该函数并获取原始异常详细信息。查看apple clang 7和gcc 5(优化O3)生成的程序集,我看不到常量引用程序集和非常量引用程序集之间的任何差异。所以,我猜gcc和apple Clangt的优化没有区别。编译器可以很容易地看到您修改了哪些对象,哪些没有(以及不断的传播)。需要更好的解释(或者这是一个神话?)“告诉编译器你不打算修改对象”-我想如果你将对象作为参数传递给函数调用,这可能会很有用。你说的“多态访问异常”是什么意思?@mango可能意味着能够调用虚拟函数(例如
std::exception
what()
函数)。如果按值捕获,则无法调用该函数并获取原始异常详细信息。查看apple clang 7和gcc 5生成的程序集(优化O3)我看不到const ref和non const ref assembly之间有任何区别。因此,我猜gcc和apple Clangt的优化没有任何区别。编译器可以很容易地看到您修改了哪些对象,哪些没有(以及不断的传播)。需要更好的解释(或者这是一个神话?)。你能详细介绍一下
异常对象在它们自己的内存空间中的情况吗?
?你对此有什么好的建议吗?@LeFlou:我可以向你指出标准,但这对我们来说有点误导