Avoid using unnamed shared_ptr temporaries to save typing; to see why
this is dangerous,consider this example:
void f(shared_ptr<int>,int); int g(); void ok() { shared_ptr<int> p(new int(2)); f(p,g()); } void bad() { f(shared_ptr<int>(new int(2)),g()); }
The function ok follows the guideline to the letter,whereas bad constructs the temporary
shared_ptr in place,admitting the possibility of a memory leak. Since
function arguments are evaluated in unspecified order,it is possible
for new int(2) to be evaluated first,g() second,and we may never get
to the shared_ptr constructor if g throws an exception. <…>The exception safety problem described above may also be eliminated by
using the make_shared or allocate_shared factory functions defined in
boost/make_shared.hpp. These factory functions also provide an
efficiency benefit by consolidating allocations.
我想我会开始使用make_shared,但是我想知道这个建议是否仍然适用于C 11 shared_ptr.我问,因为我并不完全明白为什么一个扔g()将阻止ctor被调用.
解决方法
I ask because I don’t really fully understand why it is that a throwing g() would prevent the ctor from getting called.
你不明白什么?这是操作问题的顺序,标准不需要特定的顺序.让我们把语句解压成一个表达式:
auto __temp = new int(2); auto &&__temp2 = g(); auto __temp3 = shared_ptr<int>(__temp);
你现在看到这个问题吗?如果g抛出,则__temp3永远不会被初始化.因此__temp将被泄露.
C标准不要求声明以这种方式解包.但它也不禁止它.允许编译器自由地订购这些独立的表达式,但它认为合适.