2015-05-14 5 views
5

मैं ओवरथिंकिंग कर रहा हूं (कुछ लोग सोच सकते हैं, चलो देखते हैं कि क्या होता है) एसटीएल कंटेनर और उनके तत्वों का आधार।एसटीएल कंटेनरों और उनके तत्वों की स्थिरता - जब कॉन्स का उपयोग करें?

मैं इस पर चर्चा की तलाश कर रहा हूं, लेकिन परिणाम आश्चर्यजनक रूप से विचित्र हैं। तो मैं जरूरी नहीं कि यहां एक निश्चित उत्तर की तलाश कर रहा हूं, मैं एक ऐसे चर्चा से खुश हूं जो मेरे सिर में गियर फिर से चल रहा है।

मान लें कि मेरे पास एक कक्षा है जो std :: तारों को std :: vector में रखती है। मेरी कक्षा एक शब्दकोश है जो एक शब्दकोश फ़ाइल से शब्दों को पढ़ता है। वे कभी नहीं बदला जाएगा। तो यह रूप में

std::vector<const std::string> m_myStrings; 

यह घोषणा करने के लिए हालांकि विवेकपूर्ण लगता है, मैं बिखरे हुए टिप्पणी है कि आप एक std :: वेक्टर में स्थिरांक तत्वों का उपयोग नहीं करना चाहिए, के बाद से तत्वों को आबंटित करने की आवश्यकता है पढ़ा है।

प्रश्न:

  • ऐसे मामले हैं जब स्थिरांक तत्वों std :: वेक्टर में किया जाता है (हैक्स आदि को छोड़कर)?

  • अन्य कंटेनरों में उपयोग किए जाने वाले तत्व हैं? यदि हां, तो कौन सा, और कब?

मैं मुख्य रूप से वैल्यू प्रकारों के बारे में बात कर रहा हूं, यहां पॉइंटर्स नहीं।

उत्तर

2

कोई, आपके कारण के कारण।

+0

ठीक है, एक साधारण संख्या पर्याप्त नहीं है - कम से कम इसका मतलब है कि मैं सही ढंग से समझ गया हूं। संपादित करें: मैं वास्तव में चाहता हूं कि संकलक इस उपयोग को पकड़ सके। मुझे एहसास है कि इसके कारण हैं, हालांकि नहीं। – Leander

+0

@ लिंडर: ठीक है, एक साधारण "ठीक" पर्याप्त है। –

-1

std::vector<std::shared_ptr<const std::string>> 
बजाय

उपयोग करने पर विचार?

+0

सुझाव के लिए धन्यवाद, लेकिन मैं यहां पॉइंटर्स से बचने की कोशिश कर रहा हूं, यहां तक ​​कि स्मार्ट वाले भी। :) – Leander

+0

_ "मैं मुख्य रूप से मूल्य प्रकारों के बारे में बात कर रहा हूं, यहां तत्वों के रूप में, पॉइंटर्स नहीं।" _ –

+0

किसी भी मामले में, यह प्रश्न का उत्तर नहीं देता है। – juanchopanza

2

std::vector के संदर्भ में, मुझे नहीं लगता कि क्योंकि एक std::vector स्वभाव से गतिशील है और स्मृति में "के लिए कदम" के लिए आपको "आकार बदलने के लिए आवश्यक हो सकता है यह समझ में आता है अपने टेम्पलेट पैरामीटर के साथ एक const क्वालीफायर उपयोग करने के लिए करते हैं " अपने आप।

सी ++ 03 मानक, std::vector में संगत स्मृति में संग्रहीत की गारंटी है। यह लगभग std::vector को किसी सरणी के कुछ रूपों के साथ लागू करने की आवश्यकता है। लेकिन हम गतिशील आकार बदलने वाली सरणी कैसे बना सकते हैं? हम बस इसके अंत में स्मृति को "संलग्न" नहीं कर सकते हैं - या तो अतिरिक्त नोड (और एक लिंक्ड सूची) की आवश्यकता होगी या वास्तव में भौतिक रूप से सरणी के अंत में हमारी अतिरिक्त प्रविष्टियां डालने की आवश्यकता होगी, जो या तो बाहर की होगी- सीमाएं या हमें पहले स्थान पर अधिक स्मृति को आरक्षित करने की आवश्यकता है।

इस प्रकार, मुझे लगता है कि std::vector को अतिरिक्त सरणी आवंटित करने, प्रतिलिपि बनाने या अपने सदस्यों को अंत सरणी में स्थानांतरित करने की आवश्यकता होगी, और फिर पुराने को हटा दें।

यह गारंटी है नहीं कि एक चाल या एक std::vector के लिए हर टेम्पलेट करने योग्य वस्तु के लिए कॉपी काम होगा नहीं परिवर्तन अंतर्निहित वस्तु ले जाया गया या प्रतिलिपि बनाई जा रही है - यह const क्वालीफायर जोड़ने ऐसा करने के लिए अच्छा रूप माना जाता है, लेकिन यह आवश्यक नहीं है। इसलिए, हम std::vector<const T> की अनुमति नहीं दे सकते हैं।

संबंधित: How is C++ std::vector implemented?

4

मेरी कक्षा एक शब्दकोश एक शब्दकोश फ़ाइल से शब्द पढ़ता है। वे कभी नहीं बदला जाएगा।

Encapsulation यहां सहायता कर सकता है।

क्या आपकी कक्षा vector<string> रखती है, लेकिन इसे निजी बनाएं। फिर अपनी कक्षा में एक एक्सेसर जोड़ें जो const vector<string> & देता है, और कॉलर्स को इसके माध्यम से जाना जाता है।

कॉलर्स वेक्टर को बदल नहीं सकते हैं, और वेक्टर पर operator [] उन्हें const string & सौंपेंगे, जो वास्तव में आप चाहते हैं।

+0

यह एक अच्छा सुझाव है और यह काफी है जो मैंने करने का फैसला किया। चूंकि आपके समाधान को पूरे वेक्टर की एक प्रति बनाने की आवश्यकता है, हालांकि, मैं शायद इस तरह के एक इंटरफ़ेस प्रदान करूंगा: 'शून्य iterateWords (std :: function func); ': फिर कॉलर्स स्ट्रैंग्स के साथ जो भी चाहें वह करने के लिए लैम्ब्डा फ़ंक्शन की आपूर्ति कर सकते हैं। – Leander

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