C++ 将 std::move 与 std::shared_ptr 一起使用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29643974/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using std::move with std::shared_ptr
提问by ksl
I have a function defined as follows:
我有一个定义如下的函数:
void foo(std::shared_ptr<X> x) { ... };
If I declare a shared ptr to X
:
如果我将共享 ptr 声明为X
:
std::shared_ptr<X> sourcePtr(new X(...));
I can then call foo
as follows:
然后我可以foo
按如下方式调用:
foo(std::move(sourcePtr));
or
或者
foo(sourcePtr);
I understand that if I use the first option then sourcePtr
becomes null. Does it also prevent the reference count from being incremented?
我知道如果我使用第一个选项,则sourcePtr
变为空。它是否也阻止了引用计数的增加?
If that doesn't matter, which option should I prefer? Should I be considering anything else when making such a decision?
如果这无关紧要,我应该更喜欢哪个选项?在做出这样的决定时,我是否应该考虑其他任何事情?
回答by Angew is no longer proud of SO
Yes, if you move the shared pointer into the function, then:
是的,如果将共享指针移动到函数中,则:
the original
sourcePtr
will become null, andthe reference count does not get modified.
原件
sourcePtr
将变为空,并且引用计数不会被修改。
If you know that you will no longer need the value of sourcePtr
after the function call, moving it into the function is a slight optimisation, as it saves an atomicincrement (and later decrement, when sourcePtr
goes out of scope).
如果您知道sourcePtr
在函数调用之后您将不再需要的值,将它移入函数是一个轻微的优化,因为它节省了原子增量(以及以后的减量,当sourcePtr
超出范围时)。
However, be careful that the identifier sourcePtr
is still valid for the rest of the scope, just that it holds a null pointer. Which means the compiler will not complain if you use it after the move, but if you forget it was moved from, you'll in all likelihood dereference the null. I tend to use this "optimising" move
a lot, and I've also been bitten by it a few times: more functionality is added to the function, and if you forget to undo the move
, you get a nice crash.
但是,请注意标识符sourcePtr
对作用域的其余部分仍然有效,只是它持有一个空指针。这意味着如果您在移动后使用它,编译器不会抱怨,但是如果您忘记了它是从哪里移动的,您很可能会取消对 null 的引用。我倾向于经常使用这个“优化” move
,我也被它咬过几次:更多的功能被添加到函数中,如果你忘记撤消move
,你会得到一个很好的崩溃。
So moving when you no longer need it is a slight optimisation coupled with a slight maintenance burden. It's up to you to weigh which is more important in your case.
因此,当您不再需要它时移动是一个轻微的优化加上轻微的维护负担。由您来权衡哪个对您的情况更重要。
The above assumes that there is code which actually uses sourcePtr
between its declaration and the final call to foo
(thanks to @WhozCraig for pointing it out). If there is not, you'd be muchbetter off creating the pointer right at the call site:
以上假设sourcePtr
在其声明和最终调用之间实际使用了代码foo
(感谢@WhozCraig 指出)。如果没有,你会多过创建在调用点的指针向右更好:
foo(std::make_shared<X>(...));
This way, you save the same amount of atomic operations, andyou don't have a potentially dangerous empty shared pointer lying around.
这样,您可以节省相同数量的原子操作,并且不会有潜在危险的空共享指针。