我正在尝试用 C++ 实现对象持久性模型。这个想法是有一个数据库对象充当各种 PersistentObjects 的工厂,每个 PersistentObjects 都与数据库表中的一行相关联。数据库有一个这样的方法:
PersistentObject *Database::GetObject(int ID);
这将返回一个指向具有提供的 ID 号的对象的指针(如果 ID 不存在,则返回一个空指针)。在Database类中,还有一张所有已经创建的PersistentObjects的映射:
std::map<int, PersistentObject*> _objectMap;
在内部,GetObject 做以下两件事之一:
如果这是第一次请求具有 ID 的 PersistentObject,则它查询数据库,根据结果构造一个新的 PersistentObject 实例,将该对象地址插入映射(ID 作为key) 并返回指向新对象的指针。
如果之前已加载 PersistentObject(即 ID 已作为键存在于映射中),它只会返回指向该对象的指针。
集中跟踪 PersistentObjects 的原因是我有另一个线程不断轮询数据库以了解对加载的 PersistentObjects 的更改,并向任何过时的对象发送事件。
我希望能够做的是对数据库中的中心对象映射进行垃圾收集,这样当客户端代码中没有剩余的对特定对象的引用时,该对象就会从映射中删除并删除,并且不再由更新监控线程检查。
我想用 shared_ptr 来做这个,但问题是如果我在映射中使用 shared_ptr,那么即使对象不再使用,引用计数也永远不会变为零。我无法在映射中保留指向 PersistentObject 的传统指针并从中创建多个 shared_ptr。
有没有人知道这样做的方法?我几乎需要一个 shared_ptr,它会在引用计数达到 1 而不是 0 时调用删除器。或者是否有更好的方法来实现我正在尝试做的事情?
最佳答案
最好的方法应该是向客户端返回一个shared_ptr
,但在您的 map 中存储一个weak_ptr
。 weak_ptr
不会增加引用计数,并且可以使用 lock()
轻松生成更多 shared_ptr
。不过,您必须注意对象是否过期,除非您实现了一个自定义删除器来清除“死”引用。
关于c++ - 如何在最后一个客户端完成时删除持久对象的实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35940529/