【问题标题】:How to pass shared_ptr to class with lower lifetime?如何将 shared_ptr 传递给生命周期较短的类?
【发布时间】:2016-02-21 23:32:29
【问题描述】:

我想优化我的代码。我有一个类有一个 shared_ptr 数据成员。在该类的某些方法中,我创建了需要使用该成员的对象(只是为了从 shared_ptr 指向的对象中获取信息)。我知道这些创建的对象的生命周期低于我的主类。 如何传递这个指针?我认为另一个 shared_ptrs 是不必要的(因为我保证该对象将存在)。那么我创建的课程应该得到什么?他们应该得到原始指针吗?弱点?或者最好的解决方案是获取 shared_ptr (并增加其引用计数器)?什么是最标准的解决方案?

【问题讨论】:

    标签: c++ c++11 shared-ptr smart-pointers


    【解决方案1】:

    在这种情况下,当您知道您的共享资源的生命周期将比您将指针传递给 正确 的事情要传递一个 reference原始指针

    void func(object* o)
    {
        // do stuff with o
    } 
    
    // ...
    
    std::shared_ptr<object> sp;
    
    // ...
    
    func(sp.get()); // pass raw pointer
    

    这样做的主要原因是,无论何种智能指针管理资源,该函数都是有用的。通过接受原始指针,您的函数能够接受来自共享指针以及唯一指针和任何其他第三方智能的对象指针

    传入智能指针没有任何好处,除非函数需要修改智能指针本身。

    Bjarne Straustrup 和 Herb Sutter 制定的一套很好的指南可以在这里找到:CppCoreGuidelines

    关于传递原始指针(或引用)的规则: F.7

    传递智能指针会转移或共享所有权,并且仅应在使用所有权语义时使用。不操纵生命周期的函数应该采用原始指针或引用。

    通过智能指针传递将函数的使用限制为使用智能指针的调用者。需要一个小部件的函数应该能够接受任何小部件对象,而不仅仅是那些生命周期由特定类型的智能指针管理的对象。

    【讨论】:

      【解决方案2】:

      shared_ptr 传递给不会存储资源的函数时,通过引用传递:

      void foo(const shared_ptr<T>& ptr)
      {
          // Basically just a pointer dereference
          std::cout << ptr->bar() << '\n';
      }
      
      int main()
      {
         std::shared_ptr<T> ptr{std::make_shared<T>()};
         foo(ptr);
      }
      

      这不会增加引用计数,但这很好——你实际上把它当作一个原始指针(因为你只是临时检查指针)但是以一种安全的方式,因为如果你不小心复制了它您将获得可以挽救生命的引用计数增量。 :)

      但是,如果foo 需要存储此对象的任何类型的句柄,那么您应该通过复制传递shared_ptr……或者考虑使用weak_ptr,这样您至少可以获得一些安全性。

      上述人为设计的示例非常简单,我实际上将其改为:

      void foo(const T& ptr)
      {
          std::cout << ptr.bar() << '\n';
      }
      
      int main()
      {
         std::shared_ptr<T> ptr{std::make_shared<T>()};
         foo(*ptr.get());
      }
      

      【讨论】:

      • 那里有一些小错别字,具体取决于您的意思。在调用foo 时取消引用ptr.get() 返回值,或者让foo 采用const T*
      • @JohannGerell:哦,是的,单身失踪*。谢谢。
      • 我通常只是直接取消引用智能指针以获取取消引用的指针:)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-19
      • 1970-01-01
      • 2017-06-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多