如何制作像shared_ptr这样的不拥有指针

How to make not owning pointers like shared_ptr?

本文关键字:拥有 指针 ptr 何制作 shared      更新时间:2023-10-16

在我的资源管理器中,createTexture方法应该产生一个指向纹理的指针。当只有经理拥有资源时,我想删除它。我该如何做到这一点?如果我使用shared_ptr,资源管理器将存储指向纹理的shared_ptr指针,并且将无法删除它。

class ResourceManager
{
vector<shared_ptr<Texture>> _textres;
public:
shared_ptr<Texture> CreateTexture()
{
auto tex = shared_ptr<Texture>(new Texture);
_textures.push_back(tex);
return tex;
}
}
int main
{
ResourceManager rm;
{
auto tex = rm.CreateTexture();
// Do something with texture...
}
// Problem here: ResourceManager doesn't remove the texture because he owns it
}

您需要的是:

  • weak_ptr而不是shared_ptr的矢量
  • shared_ptr的deleter函数(当作用域中不再有非弱引用时调用)在向量中查找对象并删除该条目

可以使用shared_ptr构造函数提供自定义删除程序。一定要实际删除,因为这种行为将不再是自动的。

还要注意在deleter调用期间与weak_ptr行为有关的一些混淆;您可以随时切换到原始指针,这基本上具有相同的效果,而不会出现任何棘手的问题。

请注意,这一更改使您的管理器不再"拥有"纹理,但根据您描述的语义("只有管理器拥有时删除资源">),它从未真正拥有过。

我认为您想要的是一个shared_ptr,它在计数减为1时调用回调。当管理器创建智能指针时,它会在CreateTexture()函数中注册该回调,然后在有人减少引用计数时检查是否调用它。

需要注意的角落案例:计数将从1开始,然后您不想删除它。

比较C++常见问题解答中以侵入式引用计数的智能指针为起点的实现。接下来的工作是添加一个std::function或其他可调用的对象,以便在正确的时间调用。

实现智能指针可能有点棘手,尤其是当你混合使用线程时,但对于其他起点,你可以比较标准化的boost::shared_ptr和Loki的SharedPtr的实现,后者在Alexandrescu的经典现代C++设计中有描述。

重新实现shared_ptr的另一种选择是使用其自定义deleter来调用回调,但您必须玩一些游戏才能使其工作。