2013-03-21 4 views
5

स्मार्ट पॉइंटर्स के कंटेनर में कोई आइटम जोड़ने के कई तरीके। मैं सोच रहा हूं कि आप किस तरह से जाएंगे।स्मार्ट पॉइंटर्स के कंटेनर में एक आइटम जोड़ें

class MyContainer 
{ 
private: 
    std::vector<std::unique_ptr<Item>> mItems; 

public: 
    bool Add(Item* item); 
    // This is Way 1 
    // 
    // Advantages: 
    // - Easy to add derived items, such as Add(new DerivedItem); 
    // - No interface change if smart pointer type changes to such as shared_ptr; 
    // 
    // Disadvantages: 
    // - Don't explicitly show the item to add must be allocated on heap; 
    // - If failed to add, user has to delete the item. 

    bool Add(std::unique_ptr<Item> item); 
    // This is Way 2 
    // Disadvantages and advantages are reversed from Way 1. 
    // Such as to add derived item, Add(std::unique_ptr<Item>(new DerivedItem)); 
    //             | 
    //        easy to write DerivedItem here for an error 

    bool Add(std::unique_ptr<Item>& item); 
    // This is Way 3 
    // Similar to Way 2, but when failed to add, item still exist if it is a 
    // reference of outer unique_ptr<Item> 

}; 

मैं व्यक्तिगत रूप से रास्ता 2 और 3 या रास्ता 1 का नुकसान के लिए रास्ता 1. किसी भी अधिक लाभ के लिए जाना है कि मैं 2 या 3 के लिए जाना चाहिए?

sftrabbit कई अच्छे अंक देता है। निम्नलिखित सामान्य मामले में। इसे आसानी से करने के लिए वे 2 या 3 का उपयोग कैसे करें? उपयोगकर्ता एक नया व्युत्पन्न आइटम उत्पन्न करने के लिए एक संवाद का उपयोग करता है। इसे std::unique_ptr<DerivedItem> item पर रखा गया है। 'ओके' बटन पर क्लिक करते समय, इसे कंटेनर में जोड़ा जाता है। यदि जोड़ने में विफल रहा है, तो संपादन के लिए संवाद पर वापस जाएं।

bool Add(std::unique_ptr<Item> item); 

कारण::

उत्तर

6

मैं के लिए मतदान

  1. यह समारोह हस्ताक्षर है कि ग्राहक MyContainer करने के लिए वस्तु का स्वामित्व पारित करने के लिए की जरूरत है से स्पष्ट है। यदि आप इसके बजाय विकल्प 1 चुनते हैं, तो यह अभी भी स्पष्ट नहीं है कि क्लाइंट को delete ऑब्जेक्ट स्वयं या नहीं, या भले ही उन्हें गतिशील आवंटित ऑब्जेक्ट को पारित किया जाना चाहिए।

  2. क्लाइंट को std::move के साथ स्वामित्व को स्पष्ट रूप से स्थानांतरित करने के लिए मजबूर होना पड़ता है यदि उनके पास पहले से ही नाम std::unique_ptr द्वारा प्रबंधित ऑब्जेक्ट है। वे गलती से स्वामित्व खो देंगे नहीं। विकल्प 3 स्पष्ट रूप से व्यक्त नहीं करता है कि यह स्वामित्व ले रहा है।

  3. जब हम std::make_unique (N3588) है, एक तत्व जोड़ने के लिए विधि होगा:

    container.Add(std::make_unique<Item>()); 
    

    यह new का उपयोग कर से बचा जाता है और कुछ स्थितियों में अपवाद सुरक्षा में सुधार।

  4. आपके द्वारा व्युत्पन्न वस्तुओं के लिए जो मुद्दा दिया गया है वह वास्तव में एक समस्या नहीं है। यदि आप गलत तरीके से करते हैं तो आपको संकलन-समय त्रुटि मिल जाएगी।

  5. यदि इंटरफ़ेस एक अलग प्रकार के स्मार्ट पॉइंटर का उपयोग करने के लिए बदलता है, तो ग्राहक जानना चाहता है। वे गुजरने वाली वस्तुओं को जारी रखना नहीं चाहते हैं कि वे स्वामित्व पारित कर रहे हैं अगर वास्तव में वे इसे साझा कर रहे हैं। वे विशेष रूप से जानना चाहते हैं कि विपरीत होता है या नहीं।

+0

+1, विशेष रूप से कारण के लिए 2. – us2012

+0

आइए हम एक मामले पर विचार करें। उपयोगकर्ता एक नया व्युत्पन्न आइटम उत्पन्न करने के लिए एक संवाद का उपयोग करता है। इसे 'std :: unique_ptr आइटम' पर रखा गया है। 'ओके' बटन पर क्लिक करते समय, इसे कंटेनर में जोड़ा जाता है। यदि जोड़ने में विफल रहा है, तो संपादन के लिए संवाद पर वापस जाएं। किस तरह से अधिक सुविधाजनक है? धन्यवाद। – user1899020

+0

@ user1899020 मैं अपने उत्तर के साथ चिपक रहा हूँ। यह वास्तव में आप 'MyContainer' का उपयोग कर रहे हैं के बारे में स्वतंत्र है। मैं बस अनुशंसा करता हूं कि यदि आप 'आइटम' नहीं जोड़ सकते हैं तो आप प्रचार करने के लिए अपवाद की अनुमति देते हैं। यह संभालने के लिए ग्राहक पर निर्भर है। –

2

दुर्भाग्य से पहला तरीका गंभीरता से सुरक्षा सुरक्षा समझौता करता है - आपने इंगित किया है कि हमारे नुकसान में खुद को। मुझे लगता है कि उन चिंताओं को इस विधि के किसी भी फायदे को ओवरराइड कर रहे हैं।

विशेष रूप से, व्युत्पन्न वस्तु का उपयोग करते समय दूसरी विधि के साथ संभावित त्रुटि संकलन समय पर पकड़ी जाती है, इसलिए यह परेशान है, लेकिन सुरक्षित!

मैं आपके मूल्यांकन के बारे में सहमत हूं कि यह उपयोग कार्यान्वयन के विवरण को रिसाव करता है लेकिन मेरे अनुभव में इस तरह के रिसाव अपरिहार्य है - मैं एसएफआरबीबीबी से सहमत हूं कि यह वास्तव में एक विस्तार है कि कक्षा के उपयोगकर्ता को इसके बारे में पता होना चाहिए।

bool Add(std::unique_ptr<Item>&& item); 

दिस वे 2 और रास्ता 3. अर्थात के लाभों को जोड़ती:

1

पिटारे में एक और उपकरण के रूप में इस पर विचार करें यह केवल rvalue स्वीकार करेंगे unique_ptr रों (जैसे 2), लेकिन अगर वहाँ कंटेनर में जोड़ने में कुछ विफलता है, यह स्वामित्व की तरह 3. इस्तेमाल किया जा सकता है की तरह कुछ को बनाए रखने कर सकते हैं:

void 
foo(MyContainer& c) 
{ 
    std::unique_ptr<Item> p = get_Item(); 
    try 
    { 
     c.Add(std::move(p)); 
    } 
    catch (...) 
    { 
     log_error_wtih(*p); 
    } 
} 
+0

क्या यह वैसे 2 जैसा ही है? क्या यह ऐसा कर सकता है: 'std :: unique_ptr a (नया आइटम); जोड़ें (ए); 'रास्ता 3 की तरह? – user1899020

संबंधित मुद्दे