Object cache with reference count

I want to create C ++ factory objects that will create some objects by id. Each object must have a reference count. If an object with the same ID is requested again, the same object should be returned if it is still in memory.

Although there is something holding a pointer to an object, that object will not be deleted. When there are no pointers in an object other than a pointer in the factory cache, that object is placed in the QCache and will be deleted if not re-requested for some time.

What's the best way to implement this?

+3


source to share


1 answer


This is how I will do it.

First of all, the class factory

will only contain watch pointers for the objects it creates. Thus, objects will be immediately removed if no native references exist to them without putting them in the queue.

The class then factory

returns shared pointers to the objects it creates, and those shared pointers will tell the custom deleter to unregister the deleted object from the factory map on destruction.

Assuming the objects you want to create have a constructor that takes their ID as an argument and a function get_id()

to return their ID, here's the code for the factory class:



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

};

      

And how do you use it:

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
}

      

0


source







All Articles