我有一个关于共享指针和移动语义的简单问题。想象一下,我有一个带有私有成员变量的类,如下所示:
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.如何最好地实施二传手?
答案 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
还是值。