2011-04-15 31 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 2011-04-15 03:05:12

回答

10

shared_ptr是次主要有用當一個物體沒有一個明確的擁有者(或者可能需要活過它的主人)時,所以沒有明顯的地方來銷燬它。 shared_ptr實質上成爲所有者,並且當最後的shared_ptr超出範圍時,該對象被銷燬。

當你有一個明確的所有者,就像你Pool類,並沒有必要爲Node對象活得比所屬Pool,那確實不是一個shared_ptr太大必要。你可以銷燬所有者的析構函數中的對象。

+0

謝謝,這使得它相當更清楚一點。所以你說的是'create_node()'應該返回存儲在'vector allnodes'中的原始指針?副本不是一個選項,因爲在創建時不會評估「節點」。 – bbtrb 2011-04-15 03:28:39

+3

@bbtrb:返回一個'Node *'很好,但我會建議使用'std :: vector '而不是泄漏。如果你真的不能複製'Node'(如果它是一個基類),你可以使用'boost :: ptr_vector '。 – 2011-04-15 06:47:19

+0

@bbtrb:是的,返回一個原始指針就足夠了。 – 2011-04-15 15:05:48

3

我喜歡通過weak_ptr提供對他人的訪問,您可以直接從shared_ptr < Node>構造一個weak_ptr < Node>。

用戶通常會從Pool中檢索一個weak_ptr,然後從weak_ptr < Node> .lock()構造一個shared_ptr < Node>。

這傳達給他們沒有所有權的用戶,並應注意不要保持鎖超過所需的時間 - 至少它給我:)