c++ - 带有引用计数器的对象缓存

标签 c++ qt caching

我想创建一个 C++ 对象工厂,它将通过 id 创建一些对象。每个对象都必须有一个引用计数器。如果再次请求具有相同 id 的对象,如果它仍在内存中,则必须返回相同的对象。

虽然有些东西保留了一个指向对象的指针,但这个对象不会被删除。当没有指向对象的指针,只有工厂缓存中的指针时,这个对象会被放入QCache中,如果一段时间内不再被请求,就会被删除。

实现它的最佳方法是什么?

最佳答案

下面是我的做法。

首先,工厂 类只会保存指向它实例化的对象的观察指针。这样,当不存在对它们的拥有引用时,对象将被立即删除,而不会将它们放入队列中。

然后,factory 类将返回指向它实例化的对象的共享指针,这些共享指针将指定一个自定义删除器以注销销毁时从工厂 map 中删除的对象。

假设您要实例化的对象有一个接受其 ID 作为参数的构造函数,以及一个返回其 ID 的函数 get_id(),这里是工厂类的代码:

#include <memory>
#include <unordered_map>
#include <functional>

using namespace std;
using namespace std::placeholders;

template<typename T>
class factory
{

public:

    shared_ptr<T> get_instance(int id)
    {
        auto i = m_map.find(id);
        if (i == m_map.end())
        {
            return create(id);
        }
        else
        {
            shared_ptr<T> p = i->second.lock();
            if (p == nullptr)
            {
                p = create(id);
            }

            return p;
        }
    }

    shared_ptr<T> create_instance()
    {
        shared_ptr<T> p = create(nextId);
        nextId++;
        return p;
    }

    void unregister(T* p)
    {
        int id = p->get_id();
        m_map.erase(id);
        delete p;
    }

private:

    shared_ptr<T> create(int id)
    {
        shared_ptr<T> p(new T(id), bind(&factory::unregister, this, _1));
        m_map[id] = p;
        return p;
    }

    unordered_map<int, weak_ptr<T>> m_map;
    int nextId = 0;

};

这就是您将如何使用它:

struct A
{
    A(int id) : _id(id) { }
    int get_id() const { return _id; }
    int _id;
};

int main()
{
    factory<A> f;

    {
        shared_ptr<A> pA = f.get_instance(5);
        shared_ptr<A> pB = pA;
        // ...
        // The object with ID 5 will go out of scope and get unregistered
    }

    shared_ptr<A> pA = f.get_instance(3);
    shared_ptr<A> pB = f.get_instance(3); // This will return the existing object
    //
    // Instance with ID 3 will go out of scope and get unregistered
}

关于c++ - 带有引用计数器的对象缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14663647/

相关文章:

c++ - 在 C++ 中显示小数点后五位,但如果小数点后有 0,则不打印它们

c++ - 在 Qt 的子线程中调用函数?

c - 指向指针别名的指针和 restrict 关键字

caching - 尝试使用 .htaccess 访问 "Cookie-Free"子域,但不起作用

java - 使用 Web View 清除 1 个以上 Activity 中的 Web 缓存

c++ - QFile VS ifstream。哪个更快?

c++ - 任何人都有确定麻将游戏是否获胜的算法?

c++文件不会用某个#include编译,而所有其他的都可以

c++ - 如何在 Qt 应用程序中获取 MAC 操作系统中驱动器的文件格式?

qt - qt 平台插件中的 processEvents 应该做什么?