这是 std::shared_ptr 的正确用法吗?
Posted
技术标签:
【中文标题】这是 std::shared_ptr 的正确用法吗?【英文标题】:Is this proper usage of std::shared_ptr? 【发布时间】:2021-11-18 23:15:09 【问题描述】:我想知道下面的 std::shared_ptr
的用法是否正确。
我想要对最初创建的指针做的就是将它添加到class A
上的向量中,
稍后会检索到
class A
public:
void AddToVec(std::shared_ptr<B> b)
myVec_.push_back(b);
std::vector<std::shared_ptr<B>> GetVec()
return myVec_;
private:
std::vector<std::shared_ptr<B>> myVec_;
然后在main
上,创建一个指针并通过如下方式传递
int main()
A a;
std::shared_ptr<B> ptr = std::make_shared<B>();
a.AddToVec(std::move(ptr));
std::move
在 main 函数中的用法是否正确?
可以简单地在main
上创建std::shared_ptr
并使用AddToVec
函数移动所有权吗?
【问题讨论】:
std::move()
不是必需的。
按值返回 shared_prr 的向量相当昂贵。
@πάνταῥεῖ 有必要吗?编译成功?是的,副本就足够了,但是当我们应用 move
和不应用时,它只是做不同的事情。
@Fureeish 可以使用 void AddToVec(std::shared_ptr<B>&& b)
进行优化吗?
@πάνταῥεῖ - 但这会使移动变得必要。值参数是任何值类别的接收器。
【参考方案1】:
std::move
在 main 函数中的用法是否正确?
是的,没错。如果不使用std::move
,也会编译;但是,它增加了std::shared_ptr
的引用计数。
是否可以简单地在 main 上创建共享 ptr 并使用
AddToVec
函数移动所有权?
从某种意义上说是正确的,你不想increment the reference count of the std::shared_ptr
。
在AddToVec
中需要的相同,因为b
是函数范围内的左值引用。因此,您需要将std::move
显式添加到myVec_
中,如下所示:
void AddToVec(std::shared_ptr<B> b)
myVec_.push_back(std::move(b));
另请注意,GetVec
每次都会返回成员 myVec_
的副本,您可能不希望这样做。因此,您可能需要以下一项或两项
// non-const reference to the member
std::vector<std::shared_ptr<B>>& GetVec()
return myVec_;
// const reference to the member
const std::vector<std::shared_ptr<B>>& GetVec() const /* noexcept */
return myVec_;
【讨论】:
以上是关于这是 std::shared_ptr 的正确用法吗?的主要内容,如果未能解决你的问题,请参考以下文章
这是 std::vector 和 std::shared_ptr 内存泄漏的错误吗?