1

以下是我正在尝试的玩具代码......我理解第一个和第二个。第一个将所有权授予_p. 第二个复制p_p. 但是第三个没看懂。。。

std::move是什么const shared_ptr &意思?谢谢你。

class P { };

class A {
public:
    // first one
    A(std::shared_ptr<P> &p, int) : _p(std::move(p))
    {
        std::cout << "1st Ctor: "
                  << p.use_count() << ", " << _p.use_count() << std::endl;
    }

    // second one
    A(const std::shared_ptr<P> &p, std::string) : _p(p)
    {
        std::cout << "2nd Ctor: "
                  << p.use_count() << ", " << _p.use_count() << std::endl;
    }

    // third one
    A(const std::shared_ptr<P> &p) : _p(std::move(p))
    {
        std::cout << "3rd Ctor: "
                  << p.use_count() << ", " << _p.use_count() << std::endl;
    }

private:
    std::shared_ptr<P> _p;
};

int main()
{
    {
        std::shared_ptr<P> p = std::make_shared<P>();
        A a(p, 1);
        std::cout << "1. body: " << p.use_count() << std::endl;
    }
    std::cout << "-------------" << std::endl;
    {
        std::shared_ptr<P> p = std::make_shared<P>();
        A a(p, "2");
        std::cout << "2. body: " << p.use_count() << std::endl;
    }
    std::cout << "-------------" << std::endl;
    {
        std::shared_ptr<P> p = std::make_shared<P>();
        A a(p);
        std::cout << "3. body: " << p.use_count() << std::endl;
    }
 }

结果是:

$ ./a.out 
1st Ctor: 0, 1
1. body: 0
-------------
2nd Ctor: 2, 2
2. body: 2
-------------
3rd Ctor: 2, 2
3. body: 2

(更新:添加评论以澄清哪个是第一个,第二个等)

4

2 回答 2

2

std::move只执行转换并产生 xvalue (rvalue)。

当被传递 aconst std::shared_ptr<P>时,它的返回类型将是const std::shared_ptr<P>&&。然后对于(但不移动构造函数,其将右值引用到non-const_p(std::move(p)) )的复制构造函数将被调用,效果与第二种情况相同。std::shared_ptr

基本上移动操作倾向于对被移动的对象进行修改;它不应该对const物体起作用。

于 2020-05-15T10:50:22.573 回答
0

std::move是将参数转换为右值引用的函数。函数调用是一个 xvalue 表达式。

当参数是对 const 的引用时,转换的结果是 const 的右值。如果从右值初始化为 const,将使用复制构造函数,因为移动构造函数的非 const的右值引用参数不能绑定到 const 的右值引用参数。

我认为 OP 还有一个隐含的问题,即_p(std::move(p))_p(p)

_p(std::move(p))_p(p)与的情况没有区别const std::shared_ptr<T>

理论上,如果decltype(_p)是一个具有构造函数的类型T(const T&&),那么会有区别,因为构造函数会被调用,_p(std::move(p))而不是被调用_p(p)。这样的构造器将是非常规的,但在技术上是结构良好的。std::shared_ptr没有这样的构造函数。

于 2020-05-15T10:52:47.177 回答