如何在最后一个客户端完成时删除持久对象的实例

How to delete instance of persistent object when last client has finished

我正在尝试用 C++ 实现对象持久性模型。这个想法是有一个数据库对象充当各种 PersistentObjects 的工厂,每个 PersistentObjects 都与数据库中的一行相关联 table。数据库有这样的方法:

PersistentObject *Database::GetObject(int ID);

此 returns 指向具有提供的 ID 号的对象的指针(如果 ID 不存在,则为空指针)。在数据库class中,还有一张所有已创建的PersistentObjects的映射:

std::map<int, PersistentObject*> _objectMap;

在内部,GetObject 执行以下两项操作之一:

  1. 如果这是第一次请求具有 ID 的 PersistentObject,则它查询数据库,根据结果构造一个新的 PersistentObject 实例,将该对象地址插入到映射中(用ID 作为键)和 returns 指向新对象的指针。

  2. 如果之前已加载 PersistentObject(即 ID 已经作为键存在于映射中),它只是 returns 指向该对象的指针。

集中跟踪 PersistentObjects 的原因是我有另一个线程不断轮询数据库以了解对加载的 PersistentObjects 的更改,并向任何过时的对象发送事件。

我想做的是对数据库中的中心对象映射进行垃圾收集,这样当客户端代码中没有对特定对象的剩余引用时,该对象就会从映射中移除并删除,并且不再被更新监控线程检查。

我想用 shared_ptr 来做这个,但问题是如果我在映射中使用 shared_ptr,那么引用计数永远不会变为零,即使对象不再是正在使用。我无法在地图中保留指向 PersistentObject 的传统指针并从中创建多个 shared_ptr。

有人知道这样做的方法吗?我几乎需要一个 shared_ptr,它会在引用计数达到 1 而不是 0 时调用删除器。或者有更好的方法来实现我正在尝试做的事情吗?

最好的方法应该是 return 一个 shared_ptr 给客户,但在你的地图中存储一个 weak_ptrweak_ptr 不增加引用计数,使用 lock() 可以轻松产生更多 shared_ptr。不过,您必须注意对象是否过期,除非您实现了一个自定义删除器来清理 "dead" 引用。