代码之家  ›  专栏  ›  技术社区  ›  Björn Pollex

从共享指针中分离指针?[复制品]

  •  26
  • Björn Pollex  · 技术社区  · 15 年前

    可能重复:
    How to release pointer from boost::shared_ptr?

    我的接口函数返回一个指向对象的指针。用户应该拥有该对象的所有权。我不想返回boost.shared ptr,因为我不想强制客户使用boost。但是,在内部,我希望将指针存储在共享指针中,以防止在出现异常等情况时发生内存泄漏。似乎无法将指针与共享指针分离。有什么想法吗?

    5 回复  |  直到 13 年前
        1
  •  25
  •   Community CDub    7 年前

    你要找的是 release 功能; shared_ptr 没有释放功能。 Per the Boost manual :

    问:为什么共享指针不提供release()函数?

    a.共享资源不能放弃所有权,除非它是唯一的(),因为另一个副本仍然会破坏该对象。

    考虑:

    shared_ptr<int> a(new int);
    shared_ptr<int> b(a); // a.use_count() == b.use_count() == 2
    
    int * p = a.release();
    
    // Who owns p now? b will still call delete on it in its destructor.
    

    此外,release()返回的指针很难可靠地释放,因为源共享指针可能是用自定义的删除程序创建的。

    您可以考虑两种选择:

    • 你可以用 std::tr1::shared_ptr 这将要求用户使用支持Tr1的C++库实现。 使用Boost;至少这可以让他们在两者之间选择。
    • 你可以实现你自己的 boost::shared_ptr -像共享指针一样,并在外部接口上使用它。

    你也可以看看关于这个问题的讨论 using boost::shared_ptr in a library's public interface .

        2
  •  24
  •   Magnus    13 年前

    总是有办法的:(-)

    的确,他们没有提供release()方法是有原因的,但也不可能创建一个。做你自己的删除者。第行的内容(实际上还没有编译代码,但这是一般概念):

    template <typename T>
    class release_deleter{
    public:
      release_deleter() : released_(new some_atomic_bool(false)){}
      void release() {released_->set(true);}
      void operator()(T* ptr){if(!released_->get()) delete ptr;}
    private:
      shared_ptr<some_atomic_bool> released_;
    }
    
    ..
    
    shared_ptr<some_type> ptr(new some_type, release_deleter<some_type>());
    
    ..
    
    release_deleter<some_type>* deleter = get_deleter<release_deleter<some_type>>(ptr);
    deleter->release();
    some_type* released_ptr = ptr.get();
    
        3
  •  11
  •   Éric Malenfant    15 年前

    用户应该拥有该对象的所有权。我不想返回一个boost.shared-ptr,

    shared_ptr 快件 共享 所有权,并且您希望您的接口 转移 所有制。 std::auto_ptr 因此在这里更适用。

    不过,在内部,我希望将指针存储在共享指针中,以防止出现异常时发生内存泄漏。

    再一次, SelddPPTR 可能不是做这项工作的最佳工具。为了防止例外情况下的泄漏, scoped_ptr auto_ptr 更适合。

        4
  •  4
  •   Ben Voigt    13 年前

    使用A shared_ptr 到A scoped_ptr 到资源( shared_ptr<scoped_ptr<Resource>> )。这样你就可以 SelddPPTR 的引用计数,当且仅当资源仍附加到 作用域指针 . 但是你可以把 范围范围 当你准备放弃所有权的时候。

        5
  •  2
  •   philsquared    15 年前

    正如詹姆斯所说,你不能真正分离出一个共享指针。

    您需要内部多个所有者,还是将所有权从类转移到客户机?在那种情况下 std::auto_ptr 可能合适。

    如果你担心 STD:AutoTypTR ,您可以通过 boost::scoped_ptr ,并在分发时将其分离-由客户机手动删除或将其存储在自己的智能指针中。

    如果你有多个所有者在你身边,你可以使用侵入计数。你可以在内部使用 boost::intrusive__ptr ,但在接口处传递原始指针。然后,客户机可以手动处理引用计数,或者将其存储在 boost::intrusive_ptr 他们自己(但你不能让他们依赖)