我有一个定义如下的函数:
void foo(std::shared_ptr<X> x) { ... };
如果我向
X
声明了共享的ptr:std::shared_ptr<X> sourcePtr(new X(...));
然后,我可以按以下方式调用
foo
:foo(std::move(sourcePtr));
要么
foo(sourcePtr);
我了解,如果我使用第一个选项,则
sourcePtr
会变为null。是否还会防止引用计数增加?如果没关系,我应该选择哪个选项?做出这样的决定时,我还应该考虑其他因素吗?
最佳答案
是的,如果将共享指针移到函数中,则:
sourcePtr
将变为null,而如果您知道在函数调用后将不再需要
sourcePtr
的值,则将其稍作优化,因为它可以节省原子增量(并且在sourcePtr
超出范围时降低)。但是,请注意,标识符
sourcePtr
对于其余的作用域仍然有效,只是它包含一个空指针。这意味着如果您在 move 后使用它,编译器将不会提示,但是如果您忘记了它是从原来移走的,则很可能会取消引用null。我倾向于经常使用这种“优化”的move
,而且我对此也一再感到苦恼:向该函数添加了更多功能,并且如果您忘记撤消move
,则会遇到严重的崩溃。因此,在您不再需要它时进行 move 是一个轻微的优化,加上一个轻微的维护负担。取决于您的情况,这取决于您的情况。
上面的代码假设在声明和最终调用
sourcePtr
之间有使用foo
的代码(感谢@WhozCraig指出)。如果没有,最好在 call 站点上创建指针:foo(std::make_shared<X>(...));
这样,您节省了相同数量的原子操作,并且周围没有潜在危险的空共享指针。
关于c++ - 使用std::move与std::shared_ptr,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29643974/