首页 > 解决方案 > 如何生成一个 std::shared_ptr 与其控制块具有局部性但又是另一个类的聚合?

问题描述

std::make_shared在堆上产生一个控制块/对象对,只需要一次分配,并保持控制块和对象靠近以帮助局部性。

我想这样做,除了我希望它被创建为另一个类的聚合组件。我环顾四周,但我没有看到这样的野兽。我错过了什么吗?

例如

struct Bar {};
struct Foo
{
  // This would allocate the control block and object Bar on
  // the heap, which is pointed at by Foo.
  std::shared_ptr<Bar> x;

  // Example that would allocate the control block and object Bar as
  // an aggregate part of Foo. local_shared_ptr is not an actual thing
  // in the stl that I can find.
  std::local_shared_ptr<Bar> y;
}

标签: c++stlc++17

解决方案


我希望由包含类管理生命周期,但我想要弱指针语义。可能的?

这些都不可能。

第一个,共享对象的生命周期由其他对象管理,违反了shared_ptr作为类的基本目的。关键是,只要你有一个shared_ptr,它所指向的东西就永远存在。即使使用侵入式指针,如果您获得指向它的侵入式指针并随后通过其他方式将其销毁,则您违反了侵入式指针协定。

第二个不起作用,因为弱指针语义的核心是基于控制块的生命周期可以超过控制块管理的对象的生命周期这一事实。如果两个对象的生命周期都由某个包含对象管理Foo,那么当Foo被销毁时,两者都被销毁。所以控制块的生命周期在弱指针全部被销毁之前就结束了。

所以不,这行不通。

现在是的,有一些方法可以使这样的弱指针工作,但这些方法......令人不快。它需要拥有所有此类弱指针对象的链表,并在控制块被销毁时将它们清空。但是线程安全变得不可能(想象在控制块被破坏时复制这样一个弱指针)或者需要重量级的互斥锁来进行基本的复制操作。

总的来说,你想要的根本不是std::shared_ptr为了什么。您正在寻找的是一个侵入式指针。大多数侵入性指针建议没有弱语义是有原因的。


推荐阅读