简体   繁体   English

使用std :: move与std :: shared_ptr

[英]Using std::move with std::shared_ptr

I have a function defined as follows: 我有一个定义如下的函数:

void foo(std::shared_ptr<X> x) { ... };

If I declare a shared ptr to X : 如果我向X声明一个共享ptr:

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. 据我所知,如果我使用第一个选项,那么sourcePtr将变为null。 Does it also prevent the reference count from being incremented? 它是否也会阻止引用计数递增?

If that doesn't matter, which option should I prefer? 如果这无关紧要,我更喜欢哪个选项? Should I be considering anything else when making such a decision? 做出这样的决定时,我应该考虑其他事情吗?

Yes, if you move the shared pointer into the function, then: 是的,如果将共享指针移动到函数中,则:

  1. the original sourcePtr will become null, and 原始的sourcePtr将变为null,并且

  2. the reference count does not get modified. 引用计数不会被修改。

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 atomic increment (and later decrement, when sourcePtr goes out of scope). 如果你知道在函数调用之后你将不再需要sourcePtr的值, 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. 但是,请注意标识符sourcePtr对于作用域的其余部分仍然有效,只需保留空指针即可。 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. 这意味着如果你在移动后使用它,编译器不会抱怨,但是如果你忘了它被移动了,你很可能取消引用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. 我倾向于使用这种“优化” 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). 上面假设有一些代码实际上在其声明和foo的最终调用之间使用了sourcePtr (感谢@WhozCraig指出它)。 If there is not, you'd be much better off creating the pointer right at the call site: 如果没有,你会关闭创建在调用点的指针向右好得多

foo(std::make_shared<X>(...));

This way, you save the same amount of atomic operations, and you don't have a potentially dangerous empty shared pointer lying around. 这样,您可以保存相同数量的原子操作, 并且没有潜在危险的空共享指针。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM