15

我正在用 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) {}
4

2 回答 2

32

您应该通过 const 左值引用 (2) 捕获:

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

理由:

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

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

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

于 2011-09-28T13:38:27.663 回答
1

我想应该通过左值引用以通常的方式捕获异常。这是对 rvalues-references 使用的很好的解释

于 2011-09-28T10:24:33.033 回答