关于捕获异常的良好实践

About catching exception good practices

本文关键字:捕获异常      更新时间:2023-10-16

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

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

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

原理:

在c++ 11中,有可能(通过使用shared_future)两个线程可以同时展开同一个异常。即使您没有意识到使用了shared_future,也可能在代码中发生这种情况,除非您控制了整个应用程序。

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

所以只要你不需要修改catch子句中的异常对象,让编译器为你强制执行该策略- catch by const&。如果您确实需要修改异常,那么创建它的副本,修改副本并抛出副本。您可以通过按值捕获来做到这一点,如果您确信这不会切片您的异常对象(如果您捕获std::exception,通常不是这种情况)。

我认为应该用左值引用的通常方式捕获异常。下面是对

使用值引用的很好的解释