关于捕获异常的良好实践
我正在用 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) {}
I'm writing a little program in C++11 and really use exceptions for one of the first time.
I've got a question about how to catch the exceptions efficiently, and after some googling I still don't have the answer.
Here is the question :
What is the more efficient (or recommended) between catching the exception by (const?) lvalue reference, or by (const?) rvalue reference?
In code this give :
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) {}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您应该通过 const 左值引用捕获 (2):
基本原理:
在 C++11 中,两个线程有可能(通过使用
shared_future
)同时展开相同的异常。即使您不知道正在使用shared_future
,这种情况也可能在您的代码中发生,除非您控制整个应用程序。如果两个线程同时展开相同的异常,并且一个或两个线程修改了该异常,那么就会出现竞争条件。
因此,只要您不必修改 catch 子句中的异常对象,就可以让编译器为您强制执行该策略 - catch by
const&
。如果确实需要修改异常,则复制它,修改该副本并抛出该副本。如果您确定这不会分割您的异常对象,您可以通过按值捕获来实现此目的(如果您捕获std::exception
,则通常不会出现这种情况)。You should catch by const lvalue reference (2):
Rationale:
In C++11 it is possible (via use of
shared_future
) that two threads could be unwinding the same exception at the same time. This can happen in your code even if you are not aware ofshared_future
being used, unless you control the entire application.If two threads are caught unwinding the same exception simultaneously, and one or both of the threads modifies the exception, then you've got a race condition.
So as long as you don't have to modify the exception object in the catch clause, let the compiler enforce that policy for you - catch by
const&
. If you really do need to modify the exception, then make a copy of it, modify the copy and throw the copy. You can do this by catching by value if you are sure this won't slice your exception object (which is not usually the case if you are catchingstd::exception
).我认为应该通过左值引用以通常的方式捕获异常。 这里对右值引用使用的很好的解释
I suppose that exception should be caught in usual manner by lvalue-reference. Here's good explanation of rvalues-references use