2012-05-31 27 views
6

एक class C की कल्पना करें जिसमें सदस्य m_MyList प्रकार std::vector है जिसमें मैं MyClass प्रकार की वस्तुओं को संग्रहीत करना चाहता हूं। C में दो फ़ंक्शन हैं जो m_MyList में ऑब्जेक्ट्स को जोड़ या निकालते हैं। m_MyList को C के उपभोक्ताओं के लिए भी सुलभ बनाया जाना चाहिए क्योंकि उन्हें MyClass ऑब्जेक्ट्स के संग्रह को पढ़ने की आवश्यकता है। संग्रह के बाहरी पाठक के पास संग्रह को बदलने का कोई साधन नहीं होगा, इस प्रकार MyClass ऑब्जेक्ट्स केवल C के स्वामित्व में हैं।क्या मुझे अपनी कक्षा में std :: vector सदस्य चर में std :: unique_ptr <T> का उपयोग करना चाहिए?

अब मेरा प्रश्न: सी ++ 11 शैली में, वेक्टर में स्टोर करने के लिए सबसे अच्छा टी क्या है?

  • std::vector<MyClass>
  • std::vector<MyClass*>
  • std::vector<unique_ptr<MyClass>>, std:move का उपयोग कर vector
+3

'unique_ptr' समाधान वास्तव में आपको कुछ भी नहीं खरीदता है, जब तक ऑब्जेक्ट नॉनपीपीबल हो। कच्चा सूचक संस्करण कमजोर हानिकारक है। बस सरल समाधान – jalf

+0

के लिए जाएं ऑब्जेक्ट का कितना बड़ा 'MyClass' है और आप कितने स्टोर करने की योजना बना रहे हैं? क्या बहुत सारे प्रविष्टियां होंगी? – RedX

उत्तर

13

में unique_ptr पुश करने के लिए है, तो सबसे अच्छा MyClass वस्तुओं C के स्वामित्व में हैं, तो: संभावनाओं होने लगते हैं विकल्प सबसे आसान होगा:

std::vector<MyClass> 

यहां केवल std::unique_ptrs का उपयोग करने के लिए देखे जाने का एकमात्र कारण यह है कि यदि आपको पॉलिमॉर्फिज्म के लिए बेस क्लास में पॉइंटर्स रखना है। इस मामले में अद्वितीय_प्टर वेक्टर के विनाश पर संसाधनों को जारी करने के उद्देश्य से कार्य करते हैं। लेकिन फिर C इंटरफ़ेस को ग्राहकों को स्वामित्व स्थानांतरित नहीं करना चाहिए।

+5

'MyClass' एक ऑब्जेक्ट हो सकता है जो स्थानांतरित/कॉपी करने के लिए महंगा है। एक सूचक का उपयोग करने से आप सदिश का आकार बदलने के बिना वेक्टर का आकार बदल सकते हैं। –

+1

@ edA-qamort-ora-y जो सत्य है, लेकिन यह स्वामित्व और ग्राहकों से स्वतंत्र है और इसलिए, मैंने माना कि विचार के दायरे से परे विचार होना चाहिए। – juanchopanza

+1

कक्षा के सदस्य के रूप में किसी भी प्रकार के संदर्भ प्रकार का उपयोग करने का दूसरा कारण यह सुनिश्चित करना है कि हेडर उस सदस्यों के विवरण का खुलासा न करे, जबकि इकाई फ़ाइल (सीपीपी) इसके बारे में जानती है। यह वास्तव में अलगाव के लिए अच्छा है। यहां वेक्टर की आवश्यकता है कि सदस्य को परिभाषित करने से पहले MyClass को परिभाषित किया जाए। तो आपको MyClass कोड शामिल करना होगा। कुछ मामलों में, आप यह नहीं चाहते हैं। कहा जा रहा है कि, इसकी एक अलग स्मृति और प्रबंधन लागत है, इसलिए पसंद बहुत संदर्भ विशिष्ट है। – Klaim

11

कच्चे पॉइंटर्स (std::vector<MyClass*>) गलत हैं यदि सी ऑब्जेक्ट्स का मालिक है। अन्य दो सुंदर निम्नलिखित व्यापार गत साथ इसी तरह के हैं:

  • std::vector<MyClass> - की आवश्यकता है (अतिरिक्त) गतिशील आवंटन

- copyable हो सकता है और/या ले जाने के योग्य

  • std::vector<unique_ptr<MyClass>> को MyClass की आवश्यकता है कंटेनर पर किए जा रहे संचालन भी प्रासंगिक हो सकते हैं। एक चरम उदाहरण लेने के लिए, यदि MyClass बड़ा है और कंटेनर बार-बार घुमाया जा रहा है, unique_ptr बेहतर विकल्प होगा।

  • +0

    'std :: vector' के प्रत्येक तत्व को मुफ्त स्टोर पर रखा गया है, इसलिए कह रहा है कि" गतिशील आवंटन की आवश्यकता है "जैसे कि यह एक बुरी बात है, यहां एक गलत नाम है ... – rubenvb

    +2

    @ रूबेनव: वेक्टर को केवल एक गतिशील आवंटन की आवश्यकता होती है एक समय में (या पुनर्वितरण के दौरान संक्षेप में 2)। इसलिए इसे गतिशील आवंटन की आवश्यकता नहीं है ;-) यदि 'MyClass' पर्याप्त छोटा है, तो आप अंततः अंतर देखेंगे। मुझे लगता है कि यह कहना बेहतर हो सकता है, "गतिशील आवंटन में अधिक ओवरहेड की आवश्यकता है"। यदि आप स्मृति बर्बाद करने के एकमात्र उद्देश्य के लिए अतिरिक्त कोड टाइप कर रहे हैं तो यह एक बुरी बात है। यदि * MyClass' रचनात्मक नहीं है, तो यह एक बुरी बात हो सकती है, और आप उन जगहों पर गतिशील आवंटन शुरू करते हैं जो वे अन्यथा नहीं होते हैं, इस प्रकार अपवाद प्रस्तुत करते हैं। –

    +0

    प्रत्येक व्यक्तिगत ऑब्जेक्ट का गतिशील आवंटन न केवल अधिक मेमोरी लेता है, यह विखंडन बढ़ाता है और अधिक डेटा कैश मिस का कारण बनता है। ज्यादातर कोड में, यह पूरी तरह से ध्यान देने योग्य होगा लेकिन स्टीव कहते हैं - कोड को थोड़ा और खराब करने के लिए और अधिक टाइप न करें। –

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