2009-09-05 10 views
12

मैं हमेशा एसटीएल कंटेनर (वेक्टर, सूची, मानचित्र ...) स्टोर मूल्यों के बारे में थोड़ा उलझन में रहा हूं। क्या वे मेरे द्वारा पास किए गए मानों के संदर्भों को संग्रहीत करते हैं, या क्या वे प्रतिलिपि बनाते हैं/प्रतिलिपि बनाते हैं + मूल्यों को स्वयं संग्रहित करते हैं?एसटीएल: स्टोर संदर्भ या मूल्य?

उदाहरण के लिए,

int i; 
vector<int> vec; 
vec.push_back(i); 
// does &(vec[0]) == &i; 

और

class abc; 
abc inst; 
vector<abc> vec; 
vec.push_back(inst); 
// does &(vec[0]) == &inst; 

धन्यवाद

+5

आपको मेरे पास काम करने वाले कोड की तरह दिखता है जो उत्तर का परीक्षण करेगा (टिप्पणी को एक सशर्त बनाने के लिए एक छोटे बदलाव के साथ)। इसे चलाओ और देखो! मुझे पूरा यकीन है कि वे प्रतिलिपि बनाते हैं और स्टोर करते हैं। –

उत्तर

18

एसटीएल कंटेनरों कॉपी-निर्माण और दुकान मान में गुजरती हैं। आप एक कंटेनर में वस्तुओं संग्रहीत करना चाहते हैं उन्हें कॉपी करने के बिना, मैं कंटेनर में ऑब्जेक्ट को पॉइंटर संग्रहीत करने का सुझाव दूंगा:

class abc; 
abc inst; 
vector<abc *> vec; 
vec.push_back(&inst); 

निष्क्रिय स्टैक फ्रेम पर चरों पर गलती से संदर्भों को रोकने के लिए कंटेनर कक्षाओं को लागू करने का यह सबसे तार्किक तरीका है। पर विचार करें:

class Widget { 
public: 
    void AddToVector(int i) { 
     v.push_back(i); 
    } 
private: 
    vector<int> v; 
}; 

i के लिए एक संदर्भ भंडारण खतरनाक होगा के रूप में आप जो विधि में यह परिभाषित किया गया था से लौटने के बाद एक स्थानीय चर की स्मृति स्थान को संदर्भित किया जाएगा।

+5

आप ऐसे कंटेनर नहीं बना सकते हैं जो C++ में संदर्भ संग्रहीत करते हैं। कंटेनर को पास किया गया प्रकार तर्क असाइन करने योग्य होना चाहिए। संदर्भ असाइन करने योग्य नहीं हैं, वे किसी ऑब्जेक्ट के साथ प्रारंभ किए गए हैं लेकिन निर्माण के बाद किसी भिन्न ऑब्जेक्ट को संदर्भित करने के लिए असाइन नहीं किया जा सकता है। इस प्रकार संदर्भ प्रकार कंटेनरों के अंदर उपयोग की जाने वाली प्रकार की आवश्यकताओं को पूरा नहीं करते हैं। यदि आप वही अर्थशास्त्र (या जितना करीब हो) चाहते हैं तो आपको एक संदर्भ रैपर (boost :: ref/boost :: cref) –

+3

@dribeas प्रदान करना होगा: यह उत्तर एक hypothetical के जोखिमों को समझाकर _why not_ बताता है कार्यान्वयन। मेमोरी से निपटने के लिए कंटेनरों के अंदर स्मार्ट पॉइंटर्स के उपयोग पर – MSalters

4

यह आपके प्रकार पर निर्भर करता है। यदि यह एक साधारण मूल्य प्रकार है, और प्रतिलिपि बनाने के लिए सस्ता है, तो मूल्यों को संग्रहीत करना शायद उत्तर है। दूसरी तरफ, यदि यह एक संदर्भ प्रकार है, या प्रतिलिपि बनाने के लिए महंगा है, तो आप बेहतर स्मार्ट पॉइंटर स्टोर करेंगे (auto_ptr नहीं, क्योंकि इसकी विशेष प्रति अर्थशास्त्र इसे कंटेनर में संग्रहीत होने से रोकती है। Share_ptr के लिए जाएं)। एक सादे सूचक के साथ आप स्मृति रिसाव और मुक्त स्मृति तक पहुंच का जोखिम उठा रहे हैं, जबकि संदर्भों के साथ आप बाद वाले को जोखिम दे रहे हैं। एक स्मार्ट सूचक दोनों से बचाता है।

+2

+1। संसाधन विकल्प हटाने की देखभाल करने के लिए बूस्ट पॉइंटर कंटेनर जैसी लाइब्रेरी का उपयोग करना एक और विकल्प हो सकता है –

+5

ओपी क्या नहीं पूछ रहा है। वह जानना चाहता है कि क्या कंटेनर कक्षाएं खुद को मूल्य की प्रतिलिपि बनाते हैं जब इसे कंटेनर में रखा जाता है। जवाब है, हां, वे करते हैं - यही कारण है कि विशेष प्रकार के प्रश्न की प्रतिलिपि बनाने के लिए पॉइंटर्स भंडारण अच्छा हो सकता है। –

+2

और नग्न पॉइंटर्स को संग्रहीत करना बिल्कुल ठीक है अगर आप जानते हैं कि आप क्या कर रहे हैं और अपने आप को साफ कर लें। –

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