ksl*_*ksl 28 c++ shared-ptr move-semantics c++11
我有一个定义如下的函数:
void foo(std::shared_ptr<X> x) { ... };
Run Code Online (Sandbox Code Playgroud)
如果我将共享ptr声明为X:
std::shared_ptr<X> sourcePtr(new X(...));
Run Code Online (Sandbox Code Playgroud)
然后我可以打电话foo如下:
foo(std::move(sourcePtr));
Run Code Online (Sandbox Code Playgroud)
要么
foo(sourcePtr);
Run Code Online (Sandbox Code Playgroud)
我明白,如果我使用第一个选项,则sourcePtr变为null.它是否也会阻止引用计数递增?
如果这无关紧要,我更喜欢哪个选项?做出这样的决定时,我应该考虑其他事情吗?
Rei*_*ica 38
是的,如果将共享指针移动到函数中,则:
原件sourcePtr将变为null,并且
引用计数不会被修改.
如果您知道sourcePtr在函数调用之后将不再需要值,则将其移动到函数中是一种轻微的优化,因为它会保存原子增量(以及稍后减少,当sourcePtr超出范围时).
但是,请注意标识符sourcePtr对于作用域的其余部分仍然有效,只需保留空指针即可.这意味着如果你在移动后使用它,编译器不会抱怨,但是如果你忘了它被移动了,你很可能会取消引用null.我倾向于经常使用这种"优化" move,并且我也被它咬了几次:在函数中添加了更多的功能,如果你忘记撤消它move,你会得到一个很好的崩溃.
因此,当您不再需要它时,移动是轻微的优化,同时还有轻微的维护负担.在您的情况下,由您来衡量哪个更重要.
以上假设存在实际sourcePtr在其声明和最终调用之间使用的代码foo(感谢@WhozCraig指出它).如果没有,你会多过创建在调用点的指针向右更好:
foo(std::make_shared<X>(...));
Run Code Online (Sandbox Code Playgroud)
这样,您可以保存相同数量的原子操作,并且没有潜在危险的空共享指针.