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

标签 c++ c++11 smart-pointers object-persistence

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

PersistentObject *Database::GetObject(int ID);

这将返回一个指向具有提供的 ID 号的对象的指针(如果 ID 不存在,则返回一个空指针)。在Database类中,还有一张所有已经创建的PersistentObjects的映射:

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

在内部,GetObject 做以下两件事之一:

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

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

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

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

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

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

最佳答案

最好的方法应该是向客户端返回一个shared_ptr,但在您的 map 中存储一个weak_ptrweak_ptr 不会增加引用计数,并且可以使用 lock() 轻松生成更多 shared_ptr。不过,您必须注意对象是否过期,除非您实现了一个自定义删除器来清除“死”引用。

关于c++ - 如何在最后一个客户端完成时删除持久对象的实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35940529/

相关文章:

c++ - 在构造函数中使用 C++ 中的 unique_ptr 初始化 vector

python - 找不到 swig 命令 - 在本地安装 swig 时

c++ - 虚拟多接口(interface)

C++函数模板部分特化?

c++ - 我如何强类型定义非原始类型?

c++ - 如果我将 `shared_ptr<T>&` 分配给它的另一个引用会发生什么

c++ - 用户输入字母时卡在循环中

c++ - 我们什么时候需要 std::shared_future 而不是 std::future 来进行线程间同步?

c++ - 使用预先填充的对象映射实现工厂模式

C++ 安全对象删除