关于捕获异常良好做法

时间:2011-09-28 10:15:46

标签: c++ exception c++11 try-catch rvalue-reference

我正在用C ++ 11编写一个小程序,并且第一次真正使用异常。

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

以下是问题: 通过(const?)左值引用或(const?)rvalue引用捕获异常之间的效率(或建议)是什么?

在代码中,这给出了:

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) {}

2 个答案:

答案 0 :(得分:32)

你应该通过const lvalue reference(2)来捕获:

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

理由:

在C ++ 11中,有可能(通过使用shared_future)两个线程可以同时展开同一个异常。即使您不知道正在使用shared_future,您的代码也可能发生这种情况,除非您控制整个应用程序。

如果捕获到两个线程同时展开同一个异常,并且其中一个或两个线程修改了异常,那么你就会遇到竞争条件。

因此,只要您不必修改catch子句中的异常对象,就让编译器为您强制执行该策略 - 由const&捕获。如果确实需要修改异常,则复制它,修改副本并抛出副本。如果您确定不会对异常对象进行切片(如果您捕获std::exception通常不是这种情况),则可以通过按值捕获来执行此操作。

答案 1 :(得分:1)

我认为应该通过lvalue-reference以通常的方式捕获异常。 Here's对rvalues-references的良好解释使用