我有一个定义如下的函数:

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/

    10-14 09:25