这是 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&lt;B&gt;&amp;&amp; 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 内存泄漏的错误吗?

使用std shared_ptr作为std :: map键

使用std智能指针的正确方法来确保ptr安全

“预定义”和使用命名空间和 std::shared_ptr 的正确方法是啥?

如何正确复制给定 shared_ptr 的对象

我可以使用 std::shared_ptr 在 IOCP 中包装每个 I/O 数据吗?