相同的地址,多个“shared_ptr”,enable_shared_from_this&自定义删除

时间:2012-07-09 04:13:37

标签: boost shared-ptr weak-ptr

Same address, multiple shared_ptr counters, is it forbidden by C++ standard?相关,以及围绕指向同一对象但未共享基础引用计数结构的多个shared_ptr对象的无数其他问题。

如果对象在上述问题中继承自“enable_shared_from_this”,会发生什么?我的shared_from_this()返回了什么?一个是自定义删除器还是没有自定义删除器?

struct B : boost::enable_shared_from_this<B> {
  boost::weak_ptr < B > get_weak() {
    return shared_from_this();
  }
};

void doNothing(B *) {
}

int main() {
  B * b0 = new B;

  boost::shared_ptr < B > sddb0(b0, doNothing);
  boost::weak_ptr < B > swddb0(sddb0->get_weak());
  //  Does this have a custom deleter???
  boost::shared_ptr < B > sddb1 = swddb0.lock();

  boost::shared_ptr < B > scdb0(b0);
  boost::weak_ptr < B > swcdb0(sddb0->get_weak());
  //  Does this *not* have a custom deleter???
  boost::shared_ptr < B > scdb1 = swcdb0.lock();
}

1 个答案:

答案 0 :(得分:1)

删除器与拥有的对象相关联,并将在最后一个所有者删除其引用时用于处理它,因此共享同一对象所有权的所有指针也共享删除器。删除器不存储在单个shared_ptr对象中,它与引用计数一起存储在堆上,因此共享相同计数的所有对象共享。

让我们来看看你的代码。首先,我必须修复你的代码,因为它甚至没有编译如图所示。在您的问题中测试代码总是一个好主意,以避免浪费人们的时间来修复拼写错误并添加丢失的标题。

不写这个:

B * b0 = new B;

boost::shared_ptr < B > sddb0(b0, doNothing);

正确的方法是:

boost::shared_ptr < B > sddb0(new B, doNothing);

enable_shared_from_this<B>基地有一个weak_ptr<B>成员,由shared_ptr构造函数分配,以便weak_ptrsddb0共享所有权,由shared_from_this()返回的共享指针。

所以这个问题的答案是肯定的:

//  Does this have a custom deleter???
boost::shared_ptr < B > sddb1 = swddb0.lock();

sddb1sddb0共享所有权,因此具有相同的删除功能。

您可以使用get_deleter或写入stdout中的doNothing,或使用owner_less来比较指针的所有者来测试。

这会创建一个与现有共享指针共享所有权的对象:

boost :: shared_ptr&lt; B> scdb0(B0);

enable_shared_from_this<B>基地的weak_ptr<B>成员会被上面一行重新分配,因此它与scdb0而不是sddb0共享所有权。因此,当您在该点之后调用get_weak时,它会返回一个弱指针,该指针与scdb0共享所有权,因此没有自定义删除器。同样,您可以通过查看未调用doNothing或使用owner_less来轻松验证。