2013-02-02 5 views
3

id로 일부 객체를 생성 할 C++ 객체 팩토리를 만들고 싶습니다. 각 개체에는 참조 카운터가 있어야합니다. 동일한 ID를 가진 객체가 다시 요청되면, 같은 객체가 여전히 메모리에 있다면 리턴되어야합니다.참조 캐시가있는 객체 캐시

개체에 포인터가있는 동안이 개체는 삭제되지 않습니다. 객체에 대한 포인터가 없지만 팩토리 캐시에 포인터가 있으면이 객체는 QCache에 저장되고 잠시 동안 다시 요청하지 않으면 삭제됩니다.

이것을 구현하는 가장 좋은 방법은 무엇입니까?

+1

공장에서 'shared_ptr'을 나눠주고 자체적으로 'weak_ptr'을 유지할 수 있습니다. 그런 다음 ID가 다시 요청되면'weak_ptr'을'lock() '하려고 시도합니다. 성공하면 결과로 나오는'shared_ptr'을 넘겨주고, 실패하면 새로운 객체를 만듭니다. –

답변

0

다음은 어떻게 수행할까요?

우선, factory 클래스는 인스턴스화하는 객체에 포인터를 보냄으로써 만 보유하게됩니다. 이렇게하면 객체를 대기열에 넣지 않고 객체에 대한 참조가 없으면 객체가 즉시 삭제됩니다.

다음, factory 클래스는 인스턴스 객체에 공유 포인터을 반환하고, 그 공유 포인터는 파괴시 공장의지도에서 삭제 된 개체의 등록을 취소 할 사용자 정의 Deleter가를 지정합니다.

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

}; 

그리고 그 : 개체가 여기 팩토리 클래스의 코드는, 자신의 ID를 반환하는 인수로 자신의 ID를 받아 생성자 및 기능 get_id()을 인스턴스화하려는 가정

사용 방법 :

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

캐시가 필요하기 때문에 (객체 구성이 느리다)이 작업을 수행하지 않습니다. 또한 사용자 지정 deleter가 여기에 필요하지 않다는 것을 분명히하고 싶습니다. m_map 항목이 만료되었는지 여부를 확인할 수 있습니다. 솔루션을 찾은 것 같아서 나중에 나중에 게시하겠습니다. –