我应该std ::移动一个移动构造函数中的shared_ptr? [英] Should I std::move a shared_ptr in a move constructor?

查看:217
本文介绍了我应该std ::移动一个移动构造函数中的shared_ptr?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑:

#include <cstdlib>
#include <memory>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>
using namespace std;

class Gizmo
{
public:
    Gizmo() : foo_(shared_ptr<string>(new string("bar"))) {};
    Gizmo(Gizmo&& rhs); // Implemented Below

private:
    shared_ptr<string> foo_;
};

/*
// doesn't use std::move
Gizmo::Gizmo(Gizmo&& rhs)
:   foo_(rhs.foo_)
{
}
*/


// Does use std::move
Gizmo::Gizmo(Gizmo&& rhs)
:   foo_(std::move(rhs.foo_))
{
}

int main()
{
    typedef vector<Gizmo> Gizmos;
    Gizmos gizmos;
    generate_n(back_inserter(gizmos), 10000, []() -> Gizmo
    {
        Gizmo ret;
        return ret;
    });

    random_shuffle(gizmos.begin(), gizmos.end());

}

在上面的代码中,有两个版本的 Gizmo :: Gizmo(Gizmo&&) - 一个使用 std :: move em> shared_ptr ,另一个只是复制 shared_ptr

In the above code, there are two versions of Gizmo::Gizmo(Gizmo&&) -- one uses std::move to actually move the shared_ptr, and the other just copies the shared_ptr.

这两个版本似乎都在表面上工作。一个区别(我可以看到的是)在非< - code> move 版本中 shared_ptr 的引用计数是暂时增加,但只是暂时增加。

Both version seem to work on the surface. One difference (the only difference I can see) is in the non-move version the reference count of the shared_ptr is temporarily increased, but only briefly.

我通常会前进 move shared_ptr ,但只有在我的代码清楚和一致。我在这里缺少一个考虑?

I would normally go ahead and move the shared_ptr, but only to be clear and consistent in my code. Am I missing a consideration here? Should I prefer one version over the other for any technical reason?

推荐答案

这里的主要问题是:不是由于在 shared_ptr 中额外的原子递增和递减导致的小性能差异,但是操作的语义不一致,除非您执行移动。

The main issue here is not the small performance difference due to the extra atomic increment and decrement in shared_ptr but that the semantics of the operation are inconsistent unless you perform a move.

虽然假设 shared_ptr 的引用计数只是临时的,但在语言。从中移动的源对象可以是一个临时的,但它也可以有一个更长的寿命。它可以是一个已经转换为 rvalue-reference (例如 std :: move(var))的命名变量,不是从 shared_ptr 中移动,您仍然保持与移动来源的共享所有权, code> shared_ptr 具有较小的范围,则指向对象的生命周期将不必要地扩展。

While the assumption is that the reference count of the shared_ptr will only be temporary there is no such guarantee in the language. The source object from which you are moving can be a temporary, but it could also have a much longer lifetime. It could be a named variable that has been casted to an rvalue-reference (say std::move(var)), in which case by not moving from the shared_ptr you are still maintaining shared ownership with the source of the move, and if the destination shared_ptr has a smaller scope then the lifetime of the pointed object will needlessly be extended.

这篇关于我应该std ::移动一个移动构造函数中的shared_ptr?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆