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 を引数として受け取るコンストラクターと、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
}
于 2013-02-02T16:21:29.837 に答える