【问题标题】:Can I create a boost::shared_ptr to a local variable?我可以为局部变量创建 boost::shared_ptr 吗?
【发布时间】:2013-02-12 10:53:11
【问题描述】:

我有一些方法可以引用给定的对象,还有一些方法使用boost::shared_ptr。到目前为止,在我的测试方法中,我创建了一个指向这些对象之一的shared_ptr,并将*ptr 传递给期望引用的方法。是否可以反过来做,例如在堆栈上创建一个本地对象,然后以安全的方式创建一个指向它的共享指针,以直接替代使用传统指针的&obj 运算符?

【问题讨论】:

  • 请记住,这些方法可能希望指针在返回后仍保持活动状态。如果没有,他们应该改用T&
  • 只要没有任何东西复制或存储该指针,并且在您的函数退出后没有任何内容引用该对象。如果有人期待一个指针而不是一个引用,这可能是有原因的 - 确保您传递此指针的任何函数都不会期望该对象在您的函数退出后仍然存在。
  • @MSalters,这是一个测试方法,所以一旦这个方法完成,一切都会被清理干净。不过你有一个有效的观点!

标签: c++ boost shared-ptr


【解决方案1】:

如果你发现你需要这个,那么你的代码可能有严重错误。

如果函数采用共享指针,那应该是因为它们需要延长对象的生命周期。如果它们不需要延长对象的生命周期,则应采用引用。

根据您的操作,它们无法延长对象的生命周期。如果他们需要并且不能,他们可能最终会通过您传递给他们的共享指针的副本访问超出范围的对象。轰隆隆。

这有点可能是有道理的。他们可能需要延长使用寿命,但您将确保对象保持有效的时间超过他们可能需要延长它的最长期限。但我仍然强烈建议不要这样做。它非常脆弱,使您调用的所有代码都依赖于调用代码的行为方式。

【讨论】:

  • 在某些情况下您可能需要做某事。像这样,如果您有其他接口(可能超出您的控制范围)明确期望 shared_ptrs 而不是具有指针行为的模板化参数。 +1 不过,总的来说我同意。
  • @g-makulik:问题是,如果这些接口期望shared_ptr,他们几乎肯定也期望他们可以延长对象的生命周期。否则,这些接口可能已损坏。 (当然,考虑到我们必须与之合作的现实,做 OP 想要的可能比修复它们更好。)
【解决方案2】:
#include <boost/shared_ptr.hpp>

void null_deleter(int *)
{}

int main()
{
    int i = 0;
    boost::shared_ptr<int> p(&i, &null_deleter);
}

【讨论】:

    【解决方案3】:

    您可以在表单的构造函数中传递适当的删除器:

    template<class Y, class D> shared_ptr(Y * p, D d);
    

    deleter对象必须在其operator()()中什么都不做,比如函数:

    template <typename T>
    void no_op(T*) {}
    

    然后你可以用它来构建:

    boost::shared_ptr<Foo> f(&obj, no_op<Foo>);
    

    【讨论】:

    • +1 这是@IgorR 的回答中提到的声明null_deleter 的更普遍可用的方式。
    • @g-makulik 好吧,一个更普遍可用的方式看起来像这样:-) struct null_deleter { void operator()(void const *) const {} };
    【解决方案4】:

    可以使用 c++11 的 lambda 函数:

    boost::shared_ptr<Foo> f(&obj, \[ ](Foo*){});
    

    【讨论】:

      【解决方案5】:

      您可以在构造函数中传递 null_deleter。

      #include <boost/shared_ptr.hpp>
      #include <boost/core/null_deleter.hpp>
      int main()
      {
         int a = 0;
         boost::shared_ptr<int> pi(&a, boost::null_deleter());
      }
      

      但请注意这个案例:在销毁后使用对象:

      #include <boost/shared_ptr.hpp>
      #include <boost/core/null_deleter.hpp>
      
      
      class Y
      {
      public:
          void  tryUse()
          {
               std::cout << "attempt to use :"<< (uintptr_t)(void*)this<< std::endl;
          }
          ~Y()
          {
               std::cout << "destructor: "<< (uintptr_t)(void*)this<< std::endl;
          }
      };
      
      struct Y_user
      {
           boost::shared_ptr<Y> p;
          ~Y_user()
          {
      
              std::cout << "Y_user destructor: "<< (uintptr_t)(void*)this<< std::endl;
              if (p.get())
                  p->tryUse();
          }
      };
      
      int main()
      {
          {
              Y_user yu;
              Y y;
              boost::shared_ptr<Y> p (&y, boost::null_deleter() );
              yu.p = p;
          }
      }
      

      会导致这样的控制台输出:

      destructor: 140737179995232 
      Y_user destructor: 140737179995264
      attempt to use :140737179995232
      

      【讨论】:

        猜你喜欢
        • 2012-01-17
        • 2016-03-15
        • 2022-06-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多