问题描述
为了澄清,使用 make_unique
只会在表达式中有多个分配时添加异常安全性,而不只是一个,正确吗?例如
void f(T *);
f(new T);
是完全异常安全的(就分配和内容而言),而
void f(T *,T *);
f(new T,new T);
不正确?
不仅当你有多个分配,但每当你可以投掷在不同的地方。请考虑这个:
f(make_unique< T>(),function_that_can_throw
与
f(unique_ptr< T>(new T),function_that_can_throw());
在第二种情况下,允许编译器调用(按顺序):
-
new T
-
function_that_can_throw ()
-
unique_ptr< T>(...)
显然,如果 function_that_can_throw
实际上抛出然后你泄漏。 make_unique
可以防止这种情况。
当然,第二次分配 function_that_can_throw()
的情况。
作为一般的经验法则,只需使用 make_unique
,以便您的代码一致。当你需要一个 unique_ptr
时,它总是正确的(读:异常安全),并且它对性能没有任何影响,所以没有理由不使用它(而实际上不使用它引入了很多陷阱)。
Just to clarify, using make_unique
only adds exception safety when you have multiple allocations in an expression, not just one, correct? For example
void f(T*);
f(new T);
is perfectly exception safe (as far as allocations and stuff), while
void f(T*, T*);
f(new T, new T);
is not, correct?
Not only when you have multiple allocations, but whenever you can throw at different places. Consider this:
f(make_unique<T>(), function_that_can_throw());
Versus:
f(unique_ptr<T>(new T), function_that_can_throw());
In the second case, the compiler is allowed to call (in order):
new T
function_that_can_throw()
unique_ptr<T>(...)
Obviously if function_that_can_throw
actually throws then you leak. make_unique
prevents this case.
And of course, a second allocation (as in your question) is just a special case of function_that_can_throw()
.
As a general rule of thumb, just use make_unique
so that your code is consistent. It is always correct (read: exception-safe) when you need a unique_ptr
, and it doesn't have any impact on performance, so there is no reason not to use it (while actually not using it introduces a lot of gotchas).
这篇关于异常安全和make_unique的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!