简体   繁体   English

我如何生成一个std :: shared_ptr,它具有控制块的局部性,但又是另一个类的集合?

[英]How can I produce a std::shared_ptr that has locality with it's control block but is an aggregate of another class?

std::make_shared produces, on the heap, an control block/object pair requiring only one allocation and keeping the control block and object in close proximity to help locality. std::make_shared在堆上生成只需要分配一次的控制块/对象对,并将控制块和对象保持在紧邻的位置以帮助局部性。

I'd want to do this, except I want it to be created as an aggregate component of another class. 除了要将其创建为另一个类的聚合组件之外,我想这样做。 I've looked around, but I don't see such a beast around. 我环顾四周,但没有看到这样的野兽。 Am I missing something? 我想念什么吗?

Eg 例如

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;
}

I want the lifetime to be managed by the encompassing class, but I want weak pointer semantics. 我希望生命周期由包含类来管理,但我希望指针的语义较弱。 Possible? 可能?

Neither of those is possible. 这些都不可能。

The first one, having the lifetime of the shared object managed by some other object, violates the basic purpose of shared_ptr as a class. 第一个共享对象的生命周期由其他对象管理,这违反了shared_ptr作为类的基本目的。 The point being that, so long as you have a shared_ptr , the thing it points to will always exist . 关键是,只要您有一个shared_ptr ,它指向的东西将始终存在 Even with an intrusive pointer, you've violated the intrusive pointer contract if you get an intrusive pointer to it and later destroy it via other means. 即使使用侵入式指针,如果您获得了侵入式指针协定,但随后又通过其他方式销毁了它,则您仍然违反了侵入式指针协定。

The second one doesn't work, because weak pointer semantics are at their core based on the fact that the lifetime of the control block can exceed the lifetime of the object the control block manages. 第二个不起作用,因为弱指针语义是其核心,这是基于以下事实: 控制块的生存期可能超过控制块管理的对象的生存期。 If both objects' lifetimes are managed by some containing object Foo , then when Foo is destroyed, both are destroyed. 如果两个对象的生存期都由某个包含对象Foo来管理,则当Foo被销毁时,两个对象都将被销毁。 So the control block's lifetime ends before the weak pointers have all been destroyed. 因此,在弱指针全部被销毁之前,控制块的生命周期就结束了。

So no, this doesn't work. 所以不,这是行不通的。

Now yes, there are ways to make such a weak pointer work, but those ways are... unpleasant. 现在是的,有很多方法可以使这样的弱指针起作用,但是这些方法是……令人不愉快的。 It requires having a linked list of all such weak pointer objects, and nulling them out when the control block is destroyed. 它要求拥有所有这些弱指针对象的链表,并在销毁控制块时将其清空。 But thread safety becomes either impossible (imagine copying such a weak pointer while the control block is being destroyed) or requires heavy-weight mutex locking for basic copy operations. 但是线程安全性要么成为不可能(想象一下在破坏控制块时复制这样的弱指针),要么就需要对基本复制操作进行重互斥锁定。

Overall, what you want is simply not what std::shared_ptr is for. 总体而言,您想要的不是std::shared_ptr的用途。 What you're looking for is an intrusive pointer. 您正在寻找的是侵入式指针。 And there's a reason why most intrusive pointer proposals don't have weak semantics. 而且,大多数侵入性指针建议没有弱语义是有原因的。

Aliasing constructor might help: 别名构造器可能会有所帮助:

struct Bar {};
struct Foo
{
    std::shared_ptr<Bar> x;
    Bar y;
};

auto foo = std::make_shared<Foo>();
foo->x = std::make_shared<Bar>();
std::shared_ptr<Bar> py{foo, &foo.y}; // use control block of foo

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 std :: shared_ptr,std :: weak_ptr和控制块 - std::shared_ptr, std::weak_ptr and control block 如何中断此std :: shared_ptr参考周期? - How can I break this std::shared_ptr reference cycle? 如何创建一个到std :: vector的shared_ptr? - How can I create a shared_ptr to a std::vector? 如何重新循环分配给 std::shared_ptr 的控制块 - How to re-cycle the Control Block allocated for std::shared_ptr 如何使用std :: shared_ptr进行函数重载 <void> 和另一种类型的std :: shared_ptr? - How to do function overloading with std::shared_ptr<void> and another type of std::shared_ptr? shared_ptr的控制块内部的虚函数是什么? - What is the virtual function inside of shared_ptr's Control Block? 为什么我不能在C ++ 0x中的std :: shared_ptr的向量上执行std :: copy? - Why can't I perform a std::copy on a vector of std::shared_ptr's in C++0x? 为什么 class 可以被视为 std::function<float()> 但 shared_ptr 不能被视为 std::shared_ptr <std::function<float()> &gt; </std::function<float()></float()> - Why class can be treated as std::function<float()> but shared_ptr cannot be treated as std::shared_ptr<std::function<float()>> 我如何处理 shared_ptr ++ - How can i handle shared_ptr ++ 如何将std :: shared_ptr用作类成员? - How to use std::shared_ptr as class member?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM