c++ - 当没有更多引用时,如何从缓存中删除(非侵入式)智能指针?

标签 c++ caching shared-ptr smart-pointers weak-ptr

由于我的菜鸟名声,我无法回复此 Thread ,具体是接受的答案:

I never used boost::intrusive smart pointers, but if you would use shared_ptr smart pointers, you could use weak_ptr objects for your cache.

Those weak_ptr pointers do not count as a reference when the system decides to free their memory, but can be used to retrieve a shared_ptr as long as the object has not been deleted yet.

这当然是一个直观的想法,但是,C++ 标准不支持weak_ptrs 的比较,因此它不能用作关联容器的键。这可以通过为weak_ptrs实现一个比较运算符来规避:

template<class Ty1, class Ty2>
    bool operator<(
        const weak_ptr<Ty1>& _Left,
        const weak_ptr<Ty2>& _Right
    );

这个解决方案的问题在于

(1) 比较运算符必须为每个比较获取所有权(即从weak_ptr refs 创建shared_ptrs)

(2)当最后一个管理资源的shared_ptr被销毁时,weak_ptr并没有从缓存中删除,而是一个过期的weak_ptr被保存在缓存中。

对于 (2),我们可以提供一个自定义析构函数 (DeleteThread),但是,这将需要再次从要删除的 T* 创建一个 weak_ptr,然后可以使用它从缓存。

我的问题是,是否有更好的使用智能指针的缓存方法(我使用的是 VC100 编译器,没有提升),还是我根本不明白?

干杯,丹尼尔

最佳答案

您想要实现的可能解决方案可能是

假设 T是你的对象和shared_ptr<T>是你的共享指针

  1. 只有普通的T*在您的缓存中。
  2. 为您的 shared_ptr<T> 提供自定义删除器
  3. 让您的自定义删除器删除您的 T*从缓存中删除。

这样缓存不会增加您的 shared_ptr<T> 的引用计数但在 ref 计数达到 0 时会收到通知。

struct Obj{};

struct Deleter
{
    std::set<Obj*>& mSet;
    Deleter( std::set<Obj*>& setIn  )
        : mSet(setIn) {}

    void operator()( Obj* pToDelete )
    {
        mSet.erase( pToDelete );
        delete pToDelete;
    }
};

int main ()
{

    std::set< Obj* > mySet;
    Deleter d(mySet);
    std::shared_ptr<Obj> obj1 = std::shared_ptr<Obj>( new Obj() , d );
    mySet.insert( obj1.get() );
    std::shared_ptr<Obj> obj2 = std::shared_ptr<Obj>( new Obj() , d );
    mySet.insert( obj2.get() );

    //Here set should have two elements
    obj1 = 0;
    //Here set will only have one element

    return 42;
}

关于c++ - 当没有更多引用时,如何从缓存中删除(非侵入式)智能指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8446376/

相关文章:

c++ - 相同的 c 和 c++ 程序之间的巨大速度差异

c++ - Boost.python vs Cython 用于 C++/python 接口(interface)

c++ - 正确的结构内存管理

c++ - 将多个内存块呈现为单个连续内存块的容器

java - 如何在两个数据集选项(如 DB)之间使用类似的减法来设计 Redis 搜索/扫描算法

javascript - 在内置 SPA 中禁用缓存

javascript - 服务 worker 中的缓存未定义

c++ - shared_ptr 和 this 指针

c++ - 了解 use_count 与 shared_ptr

c++ - 构造函数期望指向正在创建的实例的共享指针