当没有更多引用时,如何从缓存中删除智能指针?

2024-01-12

我一直在尝试使用智能指针来升级现有的应用程序,并且我正在尝试克服一个难题。在我的应用程序中,我有一个对象缓存,例如,我们称它们为书籍。现在,书籍的缓存是通过 ID 请求的,如果它们在缓存中,则返回它们,如果不在缓存中,则从外部系统请求对象(操作缓慢)并将其添加到缓存中。一旦进入缓存,应用程序中就可以打开许多窗口,每个窗口都可以引用该书。在以前版本的应用程序中,程序员必须维护 AddRef 和 Release,当每个使用 Book 对象的窗口关闭时,最终的 Release(在缓存管理器上)将从缓存中删除该对象并删除该对象。

您可能已经在这里发现了链条中的薄弱环节,当然是程序员记得调用 AddRef 和 Release。现在我已经转向智能指针(boost::intrusive),我不再需要担心调用 AddRef 和 Release。然而这会导致一个问题,缓存具有对该对象的引用,因此当最终窗口关闭时,缓存不会收到其他人持有该引用的通知。

我的第一个想法是定期遍历缓存并清除引用计数为 1 的对象。我不喜欢这个主意,因为这是 N 级行动,感觉不对。我想出了一个回调系统,它更好,但并不出色。我已经包含了回调系统的代码,但是我想知道是否有人有更好的方法来做到这一点?

class IContainer
{
public:
    virtual void FinalReference(BaseObject *in_obj)=0;
};

class BaseObject 
{
    unsigned int m_ref;

public:
    IContainer *m_container;

    BaseObject() : m_ref(0),m_container(0)
    {
    }

    void AddRef()
    {
        ++m_ref;
    }
    void Release()
    {
        // if we only have one reference left and we have a container
        if( 2 == m_ref && 0 != m_container )
        {
            m_container->FinalReference(this);
        }

        if( 0 == (--m_ref) )
        {
            delete this;
        }
    }
};

class Book : public BaseObject
{
    char *m_name;
public:
    Book()
    {
        m_name = new char[30];
        sprintf_s(m_name,30,"%07d",rand());
    }
    ~Book()
    {
        cout << "Deleting book : " << m_name;
        delete [] m_name;
    }

    const char *Name()
    {
        return m_name;
    }
};

class BookList : public IContainer
{
public:
    set<BookIPtr> m_books;

    void FinalReference(BaseObject *in_obj)
    {
        set<BookIPtr>::iterator it = m_books.find(BookIPtr((Book*)in_obj));
        if( it != m_books.end() )
        {
            in_obj->m_container = 0;
            m_books.erase( it );
        }
    }
};

namespace boost
{
    inline void intrusive_ptr_add_ref(BaseObject *p)
    {
        // increment reference count of object *p
        p->AddRef();
    }
    inline void intrusive_ptr_release(BaseObject *p)
    {
        // decrement reference count, and delete object when reference count reaches 0
        p->Release();
    } 
} // namespace boost

干杯 富有的


我从未使用过 boost::intrusive 智能指针,但如果您使用shared_ptr 智能指针,则可以使用weak_ptr 对象作为缓存。

当系统决定释放其内存时,这些weak_ptr指针不算作引用,但只要该对象尚未被删除,就可以用来检索shared_ptr。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

当没有更多引用时,如何从缓存中删除智能指针? 的相关文章

  • 了解 VerQueryValue

    在 MSDN 上 我注意到 VerQueryValue 函数的以下内容 lplp缓冲区 输出 低电压空洞当此方法返回时 包含指向 pBlock 指向的缓冲区中所请求版本信息的指针的地址 当关联的 pBlock 内存被释放时 lplpBuff
  • 如何在 C++ 中对四元结构进行有效排序?

    我有一个包含 x y z 和 w 成员的结构 如何高效排序 在 C 中首先按 x 然后按 y 按 z 最后按 w 如果你想实现字典排序 那么最简单的方法是使用std tie实现小于或大于比较运算符或函子 然后使用std sort http
  • 枚举 EMF 时丢失文本

    我在列举发票 emf http www mediafire com kdjwvvo7odyvwa6并将其复制到另一个但文本丢失了 令人惊讶的是 当我将其输出到窗口时 它绘制得非常完美 int CALLBACK EnhMetaFileProc
  • Debug.WriteLine() 未命中

    我正在调试 Windows 服务 通过点击F5在 Visual Studio 2010 中 使用以下代码 In 程序 cs file static void Main if Environment UserInteractive We ar
  • 为什么数组不可赋值? [复制]

    这个问题在这里已经有答案了 据我所知 C 标准禁止使用数组作为可修改的左值 即在赋值的左侧 int lhs 4 rhs 4 0 1 2 3 lhs rhs illegal 现在 我一直想知道为什么会这样 我可以看到上面的语句 以及写入数组的
  • 如何在方法模板中使用模板类型的引用传递参数?

    我目前正在努力编译以下代码 首先是包含带有方法模板的类的头文件 ConfigurationContext h class ConfigurationContext public template
  • 用于轻松动态反射的 C# 库

    是否有任何库 例如开源项目等 可以更轻松地使用复杂的反射 例如动态创建对象或类 检查实例等 Thanks 有一个LinFu http www codeproject com KB cs LinFuPart1 aspx可用的库除了反射之外还可
  • Apple IOS 上的 C# 应用程序 [已关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我有基于 C Net 的应用程序 有什么方法可以在 Apple IOS 上运行这些应用程序吗 我没有资
  • C# While 循环与 For 循环?

    在 C 中 一个问题已经困扰我一段时间了 它的 While 和 For 循环之间的实际主要区别是什么 它只是纯粹的可读性吗 在 for 循环中本质上可以做的所有事情都可以在 while 循环中完成 只是在不同的地方 举这些例子 int nu
  • 关于 FirstOrDefault 或 SingleOrDefault

    FirstOrDefault 或 SingleOrDefault 将返回什么类型的数据 假设我的查询返回 3 条记录 例如 empid ename salary 1 joy 1500 2 rob 4500 3 jen 6500 所以如果我们
  • 为什么C++中没有“NULL引用”?

    我正在阅读 C 常见问题解答 8 6 什么时候应该使用引用 什么时候应该使用指针 http www parashift com c faq lite refs vs ptrs html 特别是以下声明 可以时使用引用 必要时使用指针 上述情
  • PHP 指针与引用

    在 PHP 中 使用指针有什么区别 例如 function foo var var 3 a 0 foo a 以及参考 function foo var var 3 a 0 foo a 它们都修改了原始变量的值 但是它们内部的表示方式不同吗
  • vs2010 c++ 通过debug查看指针内容

    我正在使用 Vs2010 c 处理 2D 数组 我从一维指针开始 并使用操作 如下 class CMatrix void clear public int nRows int nCols short MyMat CMatrix CMatri
  • cmake 包括其他目录中的 h 文件

    我在 cmake 项目下进行测试时遇到问题 我的项目是这样安排的 TerrainMap PointAccumulator heightQuadGrid Test 在 TerrainMap 目录中 CMakeLists txt 文件简单地概述
  • 无法禁用 jQuery 缓存

    Update 我发现这一定是缓存问题 但我无法关闭缓存 这是我更改后的脚本
  • 如何获取数字列的确切类型,包括。规模和精度?

    有没有办法知道列中列的确切类型DataTable 现在我正在这样做 DataTable st dataReader GetSchemaTable foreach DataColumn col in st Columns var type c
  • 比较 C# 中的对象属性[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 Locked 这个问题及其答案是locked help locked posts因为这个问题是题外话 但却具有历史意义 目前不接受新的答案或互动
  • 通过开源 PCL 使用 API 查看 3D 点云

    我使用 ToF 飞行时间 相机来获取 XYZ 格式的深度数据 为了实现 3D 点云的可视化目的 我想使用开源 PCL 提供的 API 网址为http pointclouds org documentation tutorials pcl v
  • 有没有办法将复选框列表绑定到 asp.net mvc 中的模型

    我在这里寻找一种快速简便的方法来在模型中发生回发时绑定复选框列表项的列表 显然现在常见的做法似乎是这样的form GetValues checkboxList 0 Contains true 这看起来很痛苦而且不太安全 有没有一种方法可以绑
  • 在 C# 中设置风扇速度

    我知道以前有人问过这个问题 但我似乎无法让它发挥作用 我已调用以下内容 using System Management using System Management Instrumentation using System Runtime

随机推荐

  • 如何从 UIView 创建 CGLayer 进行离屏绘图

    我已经阅读了我认为是 Quartz 2D 编程指南的相关部分 但找不到以下内容的答案 他们似乎在文档中没有过多谈论 iOS 我的应用程序在UIView 我时不时地必须以某种方式更新绘图 例如更改其中一个形状的填充颜色 我保留CGPathRe
  • 访问列表视图中的自定义对象

    我目前正在构建一个应用程序 该应用程序将请求发送到网络 然后解析结果并将其放入对象的 ArrayList 中 然后 该列表将填充 ListView 我想创建一个onClickListener这将使我知道单击了哪个对象 但我找不到实现此目的的
  • 如何访问 Sharepoint 2007/2010/2013 _layouts 文件夹

    我正在尝试在该位置插入一些数据 mysiteurl layouts 因为我必须使用第三方软件 该软件使用该文件夹中存储的数据 我是机器的管理员 Windows Server 2008R2 上的 Sharepoint 2010 但 Share
  • ActiveMQ - 通过命令行删除/清除所有队列

    有没有办法通过命令行 win linux 删除 清除ActiveMQ中的所有队列 我只能找到特定队列的命令 或者也许有办法通过 activeMQ 管理员来做到这一点 同样 我只找到了如何一一删除 清除队列 这可能非常乏味 Thanks 你可
  • gitlab.com SSH 连接超时

    我尝试让 Gitlab 与 SSH 一起工作 但不行 我已完成以下步骤 1 生成ssh密钥 ssh keygen t rsa C email protected cdn cgi l email protection b 4096 2 在文件
  • WPF DataGrid 虚拟化无法正常工作?

    我有一个 DataGrid 其中有一个 DataTable 设置为其 ItemsSource DataTable 包含 24 列和约 1600 行 实际上我稍后必须加载更多行 但目前这已经够麻烦的了 尽管将列和行的虚拟化设置为活动状态 Da
  • 使用 libwebsockets 编译 libuv

    我正在尝试运行与 LWS 库一起安装的 libwebsockets test server 但它不会运行 因为 lwsts 31616 libuv support not generated in 我检查过 libuv 已安装 1 8 0
  • 可以在 Try/Except 中重试/循环吗?

    我试图了解是否可以在 Try Except 调用内部设置循环 或者是否需要重构以使用函数 长话短说 在花了几个小时学习 Python 和 BeautifulSoup 后 我设法将一些代码组合在一起来抓取 URL 列表 将数据提取到 CSV
  • 向元组添加元素的有效方法

    我想向元组添加元素 我找到了两种方法 This https stackoverflow com a 16730367 3337089 and this https stackoverflow com a 1380875 3337089答案说
  • 在 Numpy 中生成对称矩阵

    我正在尝试在 numpy 中生成对称矩阵 具体来说 这些矩阵具有随机位置的条目 并且每个条目中的内容可以是随机的 沿着主对角线 我们不关心其中有哪些条目 因此我也将它们随机化 我采取的方法是首先生成一个 nxn 全零矩阵 然后简单地循环矩阵
  • 正则表达式在引号外的特定字符上分割字符串

    如何在保留带引号的字符串的同时分割这一行 gt div a more style ui url in tray value 分割的字符在哪里 gt 产生 gt div a more style ui url in tray value 目前
  • 识别哪个文件包含某些特定的头文件

    有时 对于复杂的标头结构 可能会包含一些标头 但很难分辨出来自哪里 是否有某种工具 依赖项查看器 或一种方法如何查找 包含堆栈 哪个源 哪个标头 哪个标头 包含一个特定的头文件 如果头文件被多次包含 找到第一个包含就足够了 找到所有包含是一
  • 我可以在嵌入式交互式 Python 控制台中使用 IPython 吗?

    我使用以下代码片段将其放入 Python shell 程序中 这工作正常 但我只得到标准控制台 有没有办法做同样的事情但使用IPython http ipython scipy org shell import code class Emb
  • 虚拟Qt信号?

    在查看一些 Qt C 代码时 我遇到了这个 class Foo Q OBJECT signals virtual void someSignal const QString str int n Q UNUSED str Q UNUSED n
  • HTTP 基本身份验证和 Atlassian JIRA、Confluence 和 Bitbucket

    我在 Apache 反向代理后面的服务器上部署了 JIRA Confluence 和 Bitbucket 他们中的每一个都通过应用程序链接与其他人连接 现在 我想通过在此之前实现 HTTP 基本身份验证来添加额外的保护层 当我这样做时 我会
  • 如何将任意数量的值绑定到 mysqli 中的准备好的语句? [复制]

    这个问题在这里已经有答案了 我真的希望有人花一点时间来检查我的代码 我正在解析一些新闻内容 我可以将初始解析插入到我的数据库中 其中包含新闻 URL 和标题 我想进一步扩展它 传递每个文章链接并解析文章的内容并将其包含在我的数据库中 最初的
  • MongoDB嵌套数组交集查询

    并提前感谢您的帮助 我有一个 mongoDB 数据库 其结构如下 id objectID userID id movies movieID movieID rating rating 我的问题是 我想搜索具有 userID 3 的特定用户
  • 此应用暂时禁用使用 Google 登录的功能

    当我们尝试向 Google 进行身份验证时 我们会看到以下屏幕 我们尝试验证的应用程序用于内部开发 我们没有将其发布给我们的用户 知道为什么会发生这种情况吗 我们之前遇到过 未经验证的应用程序 屏幕 如下所示 但现在身份验证被禁用 OAut
  • NodeJS 无法读取 ubuntu 中的默认 CA

    在我们的测试环境中 我们使用我们公司签名的 SSL 连接到另一台服务器 每次建立连接时 nodejs 都会抛出异常UNABLE TO VERIFY LEAF SIGNATURE 我通过设置找到了解决方法拒绝未经授权 false 但这不适用于
  • 当没有更多引用时,如何从缓存中删除智能指针?

    我一直在尝试使用智能指针来升级现有的应用程序 并且我正在尝试克服一个难题 在我的应用程序中 我有一个对象缓存 例如 我们称它们为书籍 现在 书籍的缓存是通过 ID 请求的 如果它们在缓存中 则返回它们 如果不在缓存中 则从外部系统请求对象