2011-09-28 42 views
14

我正在用C++ 11编写一个小程序,并且首次真正使用异常。关于捕获异常良好做法

我有一个关于如何有效地捕捉异常的问题,并经过一些谷歌搜索后,我仍然没有答案。

这里是一个问题: 通过(const?)左值引用或(const?)右值引用捕获异常之间更高效(或推荐)是什么?

在代码本给予:

1)

try { throw std::exception{"what"}; } 
catch (std::exception& ex) {} 

2)

try { throw std::exception{"what"}; } 
catch (const std::exception& ex) {} 

3)

try { throw std::exception{"what"}; } 
catch (std::exception&& ex) {} 

4)

try { throw std::exception{"what"}; } 
catch (const std::exception&& ex) {} 
+1

通过右值引用捕获甚至是非法http://stackoverflow.com/q/21977340/5447906 –

回答

31

你应该const的左值参考(2)赶上:

try { throw std::exception{"what"}; } 
catch (const std::exception& ex) {} 

理由:

在C++ 11它是可能的(通过使用shared_future)那两个线程可能会同时解除相同的异常。即使您不知道使用shared_future,也可能发生在代码中,除非您控制整个应用程序。

如果两个线程同时捕捉到相同的异常,并且其中一个或两个线程修改了异常,那么您就有竞争状态。

因此,只要您不必修改catch子句中的异常对象,就让编译器为您执行该策略 - 赶上const&。如果确实需要修改异常,请复制它,修改副本并丢弃副本。如果您确信这不会分割您的异常对象(如果您正在捕获std::exception,通常不会发生),您可以通过按值捕获来实现此目的。

+0

谢谢你的回答,这真的很有帮助和清楚。 – Geoffroy

1

我想应该通过左值引用来以通常的方式捕获异常。的右值引用Here's很好的解释使用