3

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

While there is something keeping a pointer to an object, this object will not be deleted. When there is no pointers to the object but pointer in factory cache, this object is placed in QCache and will be deleted if it will not be requested again for some time.

What's the best way to implement this?

4

1 回答 1

0

这是我将如何做到的。

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

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

假设您要实例化的对象有一个接受其 ID 作为参数的构造函数和一个get_id()返回其 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
}
于 2013-02-02T16:21:29.837 回答