2011-04-15 23 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 वर्ग की तरह, और Node वस्तुओं के लिए कोई जरूरत के मालिक Pool से अधिक जीवित करने के लिए नहीं है, तो वास्तव में नहीं एक shared_ptr के लिए ज्यादा जरूरत नहीं है। आप मालिक के विनाशक में वस्तुओं को नष्ट कर सकते हैं।

+0

धन्यवाद, यह काफी बनाता है थोड़ा स्पष्ट तो आप क्या कह रहे हैं कि 'create_node() 'को एक वेक्टर ऑलोड्स' के भीतर संग्रहीत कच्चे सूचक को वापस करना चाहिए? एक प्रतिलिपि एक विकल्प नहीं है, क्योंकि सृजन पर 'नोड' का मूल्यांकन नहीं किया जाता है। – bbtrb

+3

@bbtrb: 'नोड *' लौटने पर ठीक है, लेकिन मैं इसके बजाय 'std :: vector ' (कोई रिसाव) का उपयोग करने का सुझाव नहीं दूंगा। यदि आप वास्तव में 'नोड' (यदि यह आधार श्रेणी है) की प्रतिलिपि नहीं बना सकते हैं तो आप 'boost :: ptr_vector ' का उपयोग कर सकते हैं। –

+0

@bbtrb: हाँ, कच्चे सूचक को वापस करने के लिए पर्याप्त होगा। –

3

मुझे कमजोर_पीटीआर के माध्यम से दूसरों तक पहुंच प्रदान करना पसंद है, तो आप एक कमजोर_प्टर < नोड> सीधे एक shared_ptr < नोड> से बना सकते हैं।

उपयोगकर्ता आम तौर पर पूल से कमजोर_पीआरआर पुनर्प्राप्त करेगा और उसके बाद कम____नोड> .lock() से साझा_ptr < नोड> का निर्माण करेगा।

इस उपयोगकर्ता वे स्वामित्व अधिकार नहीं है के लिए बता देते हैं, और लंबे समय तक बनाए रखने के लिए ताला नहीं की तुलना में आवश्यक है सावधान रहना चाहिए - या कम से कम यह मेरे :)