2011-03-29 19 views
9

कहें कि मेरे पास सी ++ वर्ग, Container है, जिसमें Element प्रकार के कुछ तत्व शामिल हैं। विभिन्न कारणों से, यह निर्माण के बाद सामग्री को संशोधित या बदलने के लिए अक्षम, अवांछित, अनावश्यक, अव्यवहारिक, और/या असंभव (1) है। const std::list<const Element> (2) की रेखाओं के साथ कुछ।अपरिवर्तनीय सी ++ कंटेनर वर्ग

Container एसटीएल के "कंटेनर" और "अनुक्रम" अवधारणाओं की कई आवश्यकताओं को पूरा कर सकता है। यह विभिन्न प्रकार value_type, reference, आदि जैसे यह एक डिफ़ॉल्ट निर्माता, एक प्रति निर्माता, एक const_iterator प्रकार, begin() const, end() const, size, empty प्रदान कर सकते हैं, सभी तुलना ऑपरेटरों प्रदान कर सकते हैं, और शायद rbegin() const में से कुछ, rend() const, front() , back(), operator[](), और at()

हालांकि, Container प्रदान नहीं कर सकते insert, erase, clear, push_front, push_back, गैर स्थिरांक front, गैर स्थिरांक back, गैर स्थिरांक operator[], या गैर स्थिरांक की उम्मीद अर्थ विज्ञान के साथ at। तो ऐसा लगता है कि Container "अनुक्रम" के रूप में योग्य नहीं हो सकता है। इसके अलावा, Containeroperator=, और swap प्रदान नहीं कर सकता है, और यह iterator प्रदान नहीं कर सकता है जो एक गैर-तत्व तत्व को इंगित करता है। इसलिए, यह "कंटेनर" के रूप में भी योग्य नहीं हो सकता है।

क्या कुछ कम सक्षम एसटीएल अवधारणा है कि Container मिलती है? क्या कोई "केवल-पढ़ने वाला कंटेनर" या "अपरिवर्तनीय कंटेनर" है?

यदि Container अनुरूपता के किसी भी परिभाषित स्तर को पूरा नहीं करता है, तो क्या आंशिक अनुरूपता में मूल्य है? क्या यह "कंटेनर" जैसा दिखने के लिए भ्रामक है, जब यह योग्य नहीं होता है? क्या कोई संक्षिप्त, स्पष्ट तरीका है कि मैं अनुरूपता दस्तावेज कर सकता हूं ताकि मुझे अनुरूप अर्थशास्त्र को स्पष्ट रूप से दस्तावेज न करना पड़े? और इसी तरह, इसे दस्तावेज करने का एक तरीका ताकि भविष्य के उपयोगकर्ताओं को पता चले कि वे केवल-पढ़ने वाले जेनेरिक कोड का लाभ उठा सकते हैं, लेकिन एल्गोरिदम को काम करने के लिए उत्परिवर्तित करने की अपेक्षा न करें?

अगर मैं समस्या को आराम करता हूं तो मुझे क्या मिलेगा Container असाइन करने योग्य है (लेकिन इसके तत्व नहीं हैं)? उस बिंदु पर, operator= और swap संभव हैं, लेकिन iterator को संदर्भित करना अभी भी const Element देता है। Container अब "कंटेनर" के रूप में योग्य है?

const std::list<T> लगभग Container के समान इंटरफ़ेस है। क्या इसका मतलब यह है कि न तो "कंटेनर" और न ही "अनुक्रम" है?

फुटनोट (1) मैंने इस पूरे स्पेक्ट्रम को कवर करने वाले मामलों का उपयोग किया है। मेरे पास एक कंटेनर क्लास है जो कुछ पढ़ने-योग्य डेटा को अपनाने वाला है, इसलिए इसे अपरिवर्तनीय होना चाहिए। मेरे पास एक कंटेनर है जो आवश्यकतानुसार अपनी सामग्री उत्पन्न करता है, इसलिए यह उत्परिवर्तनीय है लेकिन आप तत्वों को एसटीएल की आवश्यकता के अनुसार प्रतिस्थापित नहीं कर सकते हैं। मेरे पास अभी तक एक और कंटेनर है जो अपने तत्वों को ऐसे तरीके से संग्रहीत करता है जो insert() को इतना धीमा कर देगा कि यह कभी भी उपयोगी नहीं होगा। और आखिरकार, मेरे पास एक स्ट्रिंग है जो कोड-पॉइंट उन्मुख इंटरफ़ेस को उजागर करते समय यूटीएफ -8 में टेक्स्ट संग्रहीत करती है; एक परिवर्तनीय कार्यान्वयन संभव है लेकिन पूरी तरह से अनावश्यक है।

फुटनोट (2) यह सिर्फ चित्रण के लिए है। मुझे यकीन है कि std::list एक असाइन करने योग्य तत्व प्रकार की आवश्यकता है।

+0

प्रारंभिक तत्वों को कंटेनर में कैसे रखा जाता है? – fredoverflow

+0

@FredOverflow मेरे प्रत्येक उपयोग के मामलों के लिए अलग-अलग। एडाप्टर के लिए, मुझे पहले से आबादी वाला अनुकूलित कंटेनर दिया गया है, और मेरी कक्षा बस इसमें एक पॉइंटर रखती है। स्वयं-जनरेटिंग कंटेनर इसके तत्व बनाता है क्योंकि उन्हें कुछ म्यूटेबल पैरामीटर पर बेस का अनुरोध किया जाता है। कंटेनर जहां जेनेरिक एसटीएल-अनुरूप डालने में बहुत धीमी गति होती है, सम्मिलन के लिए कुशल गैर-एसटीएल-अनुपालन विधियां होती हैं। और यूटीएफ -8 स्ट्रिंग को अपने कन्स्ट्रक्टर में केवल बाइट सरणी या इटरेटर रेंज दी गई है। –

+0

स्पष्ट समाधान इटरेटर्स का उपयोग करना है, या उन्हें एक परिवर्तनीय कंटेनर से अपरिवर्तनीय 'कंटेनर' में ले जाना है। –

उत्तर

1

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

(यदि लागू हो, Boost.Iterators पुस्तकालय को देखो, यह iterator_facade और iterator_adaptor वर्ग हैं बुनियादी तथ्य विवरण के साथ मदद करने के लिए)

2

एसटीएल किसी भी कम अवधारणाओं को परिभाषित नहीं करता; अधिकांशतः const का विचार प्रति-स्तर स्तर पर नहीं, प्रति-पुनरावर्तक या प्रति-संदर्भ स्तर पर व्यक्त किया जाता है।

आपको अप्रत्याशित अर्थशास्त्र के साथ iterator प्रदान नहीं करना चाहिए, केवल const_iterator प्रदान करें। यह क्लाइंट कोड को सबसे तार्किक स्थान (सबसे पठनीय त्रुटि संदेश के साथ) में विफल होने की अनुमति देता है यदि वे कोई गलती करते हैं।

संभावित रूप से ऐसा करने का सबसे आसान तरीका यह है कि इसे समेकित करना और सभी गैर-कॉन्स उपनामों को रोकना होगा।

class example { 
    std::list<sometype> stuff; 
public: 
    void Process(...) { ... } 
    const std::list<sometype>& Results() { return stuff; } 
}; 

अब कोई क्लाइंट कोड जानता है कि वे परिणाम-नाडा के वापसी मूल्य के साथ क्या कर सकते हैं जिसके लिए उत्परिवर्तन की आवश्यकता है।

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