2011-04-15 3 views
8

shared_ptr<>에 대한 경험이없는 경우 다음이 적합한 유즈 케이스인지 궁금하고 shared_ptr<>을 사용자에게 반환하는 것이 좋습니다.shared_ptr의 적절한 사용?

노드 사이에 여러 개의 연결이있는 구조의 그래프가 있습니다. 그래프를 탐색하는 동안 각 노드에는 연결된 노드에서 계산 된 값이 할당되며 사용자가 값에 쉽게 액세스 할 수 있기를 원합니다. 이런 모든 것은 외모 (강하게 간체) :

class Pool; 
class Node { 
    public: 
     typedef std::tr1::shared_ptr<Node> Ptr; 
     ... 
     void compute_dependencies() { 
      ... 
      // calls Pool to get a new Node instance 
      dependencies_.push_back(Pool::create_node(...)); 
      ... 
     } 

     // evaluate the current node 
     void evaluate() { /* use dependencies_ */ };   
     double value() const { if(evaluated) return value_; }; 

    private: 
     std::vector<Node::Ptr> dependencies_;   // vector<Node*> better? 
     dbl value_; 
} 

// Pool creates and owns all nodes 
class Pool { 
    public: 
     static const Node::Ptr create_node(...);   // create a new node 
     void traverse_and_evaluate();  

    private: 
     std::vector<Node::Ptr> allnodes; // appropriately sorted to ensure 
              // dependencies are evaluated 
     ... 
} 

사용자 전화 :

Pool pool(); 
Node::Ptr node1 = Pool::create_node(...); 
Node::Ptr node2 = Pool::create_node(...); 
.... 
pool.traverse_and_evaluate(); 
// ready to read out the now populated values 
cout << node1->value() << " " << node2->value() << ... 

이 사용자가 직접 얻을 그는 대한 관심 노드에 액세스 할 수 있다는 이점이있다 (의존성은 종종 시시한). 하지만 이것이 좋은 생각인지 100 % 확신 할 수는 없습니다.

입력 해 주셔서 감사합니다.

편집 : 순환 종속성이 없습니다.

+0

이 질문과 답변은 다소 관련성이 있습니다. http://stackoverflow.com/questions/5629592/resource-leak-during-object-creation-c/ – Anton

답변

10

shared_ptr을에 수행은 시간에 주로 유용 객체에 명확한 소유자가 없거나 소유주보다 오래 있어야하는 경우 객체를 파기 할 명확한 장소가 없습니다. shared_ptr은 본질적으로 소유자가되며, 마지막에 shared_ptr이 범위를 벗어나면 개체가 파괴됩니다.

당신이 당신의 Pool 클래스처럼 명확한 소유자를 가지고

하고 소유 Pool 오래 살 수있는 Node 객체에 대한 필요가 없습니다, 그럼 정말 shared_ptr 훨씬 필요가 없습니다. 소유자의 소멸자에서 객체를 파괴 할 수 있습니다.

+0

감사합니다. 조금 더 명확 해. 그래서 당신이 말하는 것은'create_node()'는'벡터 allnodes' 안에 저장된 원시 포인터를 리턴해야한다는 것입니다. 'Node'는 생성시 평가되지 않으므로 사본은 옵션이 아닙니다. – bbtrb

+3

@bbtrb :'Node *'를 반환하는 것은 괜찮지 만 대신'std :: vector '(누수가 없음)을 사용할 것을 제안합니다. 'Node'를 복사 할 수 없다면 (기본 클래스 인 경우)'boost :: ptr_vector '를 사용할 수 있습니다. –

+0

@bbtrb : 예, 원시 포인터를 반환하면 충분합니다. –

3

weak_ptr을 통해 다른 사용자에게 액세스를 제공하려는 경우 < 노드에서 weak_ptr 노드>를 직접 생성 할 수 있습니다.

사용자는 일반적으로 풀에서 weak_ptr을 검색 한 다음 weak_ptr 노드노드> .lock()에서 shared_ptr 노드 < 노드를 생성합니다.

이 그들이 소유 권한이없는 사용자에게 전달하고, 필요 이상으로 긴 잠금을 유지하지 않도록주의해야한다 - 또는 적어도 그것은 나 :

관련 문제