【问题标题】:How to attach boost::shared_ptr (or another smart pointer) to reference counter of object's parent?如何将 boost::shared_ptr (或另一个智能指针)附加到对象父级的引用计数器?
【发布时间】:2010-05-03 00:56:37
【问题描述】:

我记得以前遇到过这个概念,但现在在 Google 中找不到。

如果我有一个A类型的对象,它直接嵌入了一个B类型的对象:

class A {
    B b;
};

我怎样才能有一个指向B 的智能指针,例如。 G。 boost::shared_ptr<B>,但使用 A 的引用计数?假设A 的实例本身是堆分配的,我可以使用enable_shared_from_this 安全地获取其共享计数。

【问题讨论】:

  • @Marcelo Cantos,例如通过 TCP 连接处理消息:要从套接字读取,您需要提供一个连续的缓冲区,但您希望能够对离散消息进行操作(将它们排队,通过他们周围)。因此,您可以制作额外的消息副本(占用两倍的内存,可能导致碎片),或者您可以在每条消息的 shared_ptr 中重新计算缓冲区(如果每条消息都是 POD 并直接映射到缓冲区中的某个位置)。这样,当最后一条消息的 shared_ptr 被破坏时,缓冲区将被删除(或返回池等)。
  • PS 也就是说,如果你不能将 shared_ptr 保存到消息中的缓冲区,因为它需要是 POD 类型。
  • 或者,如果您将某个对象嵌入到另一个对象中,并使用期望 shared_ptr 来嵌入对象的 API(可能有多种原因导致您无法将嵌入对象转换为堆分配对象) .

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


【解决方案1】:

天啊!

shared_ptr 文档中找到它。这称为别名(参见section III of shared_ptr improvements for C++0x)。

我只需要使用不同的构造函数(或相应的reset 函数重载):

template<class Y> shared_ptr( shared_ptr<Y> const & r, T * p );

这样的工作方式(您需要先将 shared_ptr 构造为父级):

#include <boost/shared_ptr.hpp>
#include <iostream>

struct A {
    A() : i_(13) {}
    int i_;
};

struct B {
    A a_;
    ~B() { std::cout << "B deleted" << std::endl; }
};

int
main() {
    boost::shared_ptr<A> a;

    {
        boost::shared_ptr<B> b(new B);
        a = boost::shared_ptr<A>(b, &b->a_);
        std::cout << "ref count = " << a.use_count() << std::endl;
    }
    std::cout << "ref count = " << a.use_count() << std::endl;
    std::cout << a->i_ << std::endl;
}

【讨论】:

  • @StephenNutt 即使将shared_ptr 转换为派生类到基类也涉及到别名。
【解决方案2】:

我还没有对此进行测试,但是只要仍然需要孩子,您就应该能够使用custom deallocator object 将 shared_ptr 保留给父母。大致如下:

template<typename Parent, typename Child>
class Guard {
private:
   boost::shared_ptr<Parent> *parent;
public:
   explicit Guard(const boost::shared_ptr<Parent> a_parent) {
      // Save one shared_ptr to parent (in this guard object and all it's copies)
      // This keeps the parent alive.
      parent = new boost::shared_ptr<Parent>(a_parent);
   }
   void operator()(Child *child) {
      // The smart pointer says to "delete" the child, so delete the shared_ptr
      // to parent. As far as we are concerned, the parent can die now.
      delete parent;
   }
};

// ...

boost::shared_ptr<A> par;
boost::shared_ptr<B> ch(&par->b, Guard<A, B>(par));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-25
    • 2020-07-10
    • 1970-01-01
    • 1970-01-01
    • 2019-11-22
    • 1970-01-01
    • 2010-10-18
    • 1970-01-01
    相关资源
    最近更新 更多