shared_ptr完全在堆栈上

shared_ptr entirely on stack

本文关键字:堆栈 ptr shared      更新时间:2023-10-16

假设我知道堆栈帧的寿命将超过shared_ptr的所有副本,有没有办法创建堆栈对象的shared_ptr,以便参考计数器也在堆栈上,以便在任何时候都没有动态分配?

例如

SomeObject anObject;
std::shared_ptr::ref_counter refCounter; // Does this exist?
std::shared_ptr<SomeObject>(&anObject, &refCounter, [](SomeObject* obj){
obj->DoSomething();
});

这里的目标是使用shared_ptr进行引用计数,而不是作为智能指针。

编辑:我将添加更多解释,以使这样做的原因更加清晰。

我正在尝试创建一个令牌,当它及其所有副本被销毁时,我正在编写的线程库调用函数。每个令牌本质上只是一个智能指针的包装器,指向持久对象,该持久对象保存函数并在其析构函数中调用它。复制令牌会复制包装器(从而复制智能指针),但不复制持久对象。

鉴于这些令牌可能会传递给许多不同的线程,持久对象通常需要在堆上,但有时我实际上可以保证特定的堆栈帧将比它创建的任何令牌的所有副本都长寿。在这些情况下,可以在堆栈上创建令牌的持久部分,从而放弃任何昂贵的堆分配。

因此,在某些情况下,智能指针确实需要实际拥有它所指向的对象,但在其他情况下则不需要。

无法使用共享指针管理堆栈分配的对象。

但是,也不需要它。代替共享指针,您可以使用裸指针或引用。由于您知道引用的对象将超过所有用户的寿命,因此它是安全的。


我正在尝试创建一个令牌,该令牌在函数及其所有副本被销毁时调用函数

为此,您不想使用共享指针。您应该只实现自己的引用计数器。

你可以这样做,但这不是一个好的选择*。


SomeObject anObject;
std::shared_ptr<SomeObject>(&anObject, [](auto x){}});

科里鲁示例


*这不使用shared_ptr的大部分功能,是一种浪费,计数可以通过许多其他方式记录,包括实现您自己的计数类。


我真的认为没有理由阻止动态分配。即使您不能使用堆,动态分配也可以完全在堆栈上进行。