将过期weak_ptr<T>转换为shared_ptr<T>的语法

Syntax for converting expired weak_ptr<T> to shared_ptr<T>

本文关键字:gt lt ptr shared 语法 转换 weak 过期      更新时间:2023-10-16

据我所知,shared_ptr<T>不会被取消分配,直到对它的强引用和弱引用都被删除。

我理解一个共享对象在没有强引用时被认为是过期的。因此,weak_ptr<T>的标准lock()函数在这种情况下会失败,因为对象被认为是'过期'。

但是,如果共享指针的删除器被覆盖,这样管理对象就不会被删除,那么从weak_ptr<T>生成shared_ptr<T>应该是有效的-但是我找不到正确的语法来做这件事。

std::shared_ptr<int> s_ptr(new(42), D());
std::weak_ptr<int) w_ptr(s_ptr);
s_ptr.reset();
s_ptr = std::shared_ptr<int>(w_ptr, false);

编辑

为了进一步澄清这一点,我试图构建一个可重用的shared_ptr<T>对象池。这是因为每次使用shared_ptr都会导致一个或多个堆内存分配。因此,我为每个shared_ptr<T>添加了一个删除器,该删除器存储weak_ptr<T>引用,这样,删除器被调用后,它应该能够将自己重新添加到可用的shared_ptr<T>对象池中(托管对象完整)。通过将weak_ptr<T>存储在shared_ptr<T>的删除器中,因此它不应该阻止对删除器的调用。

最终目标是获得一个不做一致堆分配的智能指针-或者至少只有一小部分。

从我读到的,shared_ptr不会被取消分配,直到对它的强引用和弱引用都被删除。

是错误的。std::shared_ptr有两个块——一个控制块包含引用计数等,然后另一个块用于实际数据。

当共享计数变为0时,数据块(通常)被释放。这就是为什么从过期的std::weak_ptr中生成std::shared_ptr是非法的。

另一个注意事项,为什么你想要这个功能?它破坏了std::weak_ptr的整个要点,即能够"存储"指向std::shared_ptr存储的对象的指针,而不增加其引用计数。如果你想这样做,那么请使用std::shared_ptr

如果池化控制块是个好主意,那么库实现可能已经在做了。事实上,new的实现本身可能已经在进行池化以支持类似的内存使用模式。

此外,您可以通过使用make_shared而不是调用new并将其传递给shared_ptr构造函数来实现我认为您的目标;这个辅助函数存在的原因之一是,它可以编写为使用单个分配来同时分配控制块正在创建的新对象。