如何移动shared_ptr的数据?

时间:2014-03-11 19:45:10

标签: c++11 shared-ptr move-semantics

我有一个关于共享指针和移动语义的简单问题。想象一下,我有一个带有私有成员变量的类,如下所示:

class C
{
private:
    std::shared_ptr<std::vector<uint8_t>> buffer;
}

我需要提供公共getter和setter。吸气剂似乎很明显:

std::shared_ptr<std::vector<uint8_t>> C::GetBuffer()
{
    return buffer;
}

然而,作为C ++的新手,我在编写setter时遇到了麻烦。我可以这样做:

void C::SetBuffer(std::shared_ptr<std::vector<uint8_t>> input)
{
    buffer = input;
}

然而,这导致缓冲区的输入副本,但我真的不希望调用者拥有共享所有权。相反,我想移动数据。我尝试用以下方法解决这个问题:

void C::SetBuffer(std::shared_ptr<std::vector<uint8_t>>& input)
{
    buffer(std::move(input));
}

但这是一个错误:“没有适当的operator()或转换函数调用类类型的对象到指针到函数类型。”

有人可以帮我理解:
1.这里发生了什么? 2.如何最好地实施二传手?

2 个答案:

答案 0 :(得分:1)

如果您的目标是允许调用者将缓冲区的唯一所有权传递给您的对象,则应该unique_ptr而不是shared_ptr接受它:

void C::SetBuffer(std::unique_ptr<std::vector<uint8_t>> input)
{
    buffer = std::move(input);
}

为此,Rvalue unique_ptr可转换为shared_ptr

答案 1 :(得分:0)

您可以通过编写以下内容来解决您遇到的错误:

void C::SetBuffer( std::shared_ptr<std::vector<uint8_t> > &input ) {
    buffer = move(input);
}

这将调用shared_ptr的移动分配运算符,它将窃取input。但是,这不会真正阻止调用者拥有共享所有权。一旦你从一个未知的客户接受(或分发)shared_ptr,你就没有太多控制权来分享所有权。即使input被盗,也没有理由认为input是您刚刚收到的shared_ptr的唯一副本。例如,如果调用SetBuffer()的函数通过值从 调用者获取input的任何内容,则指针的更高级别副本将继续分享所有权。

请注意,您的getter有类似的问题。您将shared_ptr返回到您自己的内部对象(更重要的是,它是shared_ptr - 非 - const,因此客户端可以修改共享状态)以及任何位置<{1}}在您提供后传递,这些副本也将共享(可变)所有权。

如果你真的想确保拥有独家所有权,你可以持有shared_ptr而不是unique_ptr并让你的获取者传回shared_ptr - 参考,并且你的二传手是const还是值。