Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带有引用计数器的对象缓存 < >我想创建一个C++对象工厂,它将通过ID创建一些对象。每个对象必须有一个引用计数器。如果再次请求具有相同id的对象,则如果该对象仍在内存中,则必须返回该对象_C++_Qt_Caching - Fatal编程技术网

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

带有引用计数器的对象缓存 < >我想创建一个C++对象工厂,它将通过ID创建一些对象。每个对象必须有一个引用计数器。如果再次请求具有相同id的对象,则如果该对象仍在内存中,则必须返回该对象,c++,qt,caching,C++,Qt,Caching,当有东西将指针保留到某个对象时,该对象将不会被删除。当工厂缓存中没有指向该对象的指针,而是指向该对象的指针时,该对象将放置在QCache中,如果在一段时间内不再请求该对象,则该对象将被删除 实现这一点的最佳方法是什么?以下是我将如何做到这一点 首先,factory类将只保存指向它实例化的对象的观察指针。这样,当不存在对对象拥有的引用时,对象将立即被删除,而不会将它们放入队列中 然后,工厂类将返回共享指针到它实例化的对象,这些共享指针将指定一个自定义删除器,以便在销毁时从工厂映射中注销已删除的对象

当有东西将指针保留到某个对象时,该对象将不会被删除。当工厂缓存中没有指向该对象的指针,而是指向该对象的指针时,该对象将放置在QCache中,如果在一段时间内不再请求该对象,则该对象将被删除


实现这一点的最佳方法是什么?

以下是我将如何做到这一点

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

然后,
工厂
类将返回共享指针到它实例化的对象,这些共享指针将指定一个自定义删除器,以便在销毁时从工厂映射中注销已删除的对象

假设要实例化的对象有一个接受其ID作为参数的构造函数,以及一个返回其ID的函数
get_ID()
,下面是factory类的代码:

#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;

};
#包括
#包括
#包括
使用名称空间std;
使用名称空间std::占位符;
模板
阶级工厂
{
公众:
共享\u ptr获取\u实例(int-id)
{
自动i=m_map.find(id);
if(i==m_map.end())
{
返回创建(id);
}
其他的
{
shared_ptr p=i->second.lock();
如果(p==nullptr)
{
p=创建(id);
}
返回p;
}
}
共享\u ptr创建\u实例()
{
共享_ptr p=create(nextId);
nextId++;
返回p;
}
无效注销(T*p)
{
int id=p->get_id();
m_映射擦除(id);
删除p;
}
私人:
共享ptr创建(int id)
{
共享_ptr p(新的T(id),绑定(&factory::unregister,this,_1));
m_map[id]=p;
返回p;
}
无序地图;
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
}
结构A { A(int-id):_-id(id){} int get_id()常量{return_id;} 内部id; }; int main() { f厂; { 共享_ptr pA=f.get_实例(5); 共享_ptr pB=pA; // ... //ID为5的对象将超出范围并被注销 } 共享_ptr pA=f.get_实例(3); shared_ptr pB=f.get_instance(3);//这将返回现有对象 // //ID为3的实例将超出范围并被注销 }
您的工厂可以分发
共享的ptr
s,并且自己保留
弱ptr
。然后,当再次请求ID时,尝试
lock()
弱\u ptr。如果成功,则分发生成的
共享\u ptr
,如果失败,则生成一个新对象。这对我的任务不起作用,因为我需要缓存(对象构造很慢)。另外,我想说明的是,这里不需要自定义删除器,只需检查m_映射项是否过期即可。看来我找到了一个解决办法,我希望以后我会把它贴在这里。