खुद को लिखने वाले हीटर शायद ही कभी सुंदर हैं। अपने वर्गों में एक इटरेटर जोड़ने का सबसे पहला तरीका मौजूदा एक का पुन: उपयोग करना है। आपको अवगत होना चाहिए, उदाहरण के लिए पॉइंटर्स सी ++ में इटरेटर्स जितना अच्छा है, इसलिए वास्तव में अपना खुद का लिखने के बिना एक इटरेटर प्रदान करने के कई तरीके हैं।
यह मूल रूप से सी ++ कई तरीकों से कैसे काम करता है। यह लाइब्रेरी लेखकों पर बहुत अधिक बोझ डालकर अंतिम उपयोगकर्ताओं के लिए भाषा व्यय करने योग्य और सरल बनाने की कोशिश करता है। अर्थात। लाइब्रेरी लेखकों को सभी अनौपचारिक सामान लिख सकते हैं, इसलिए अंतिम उपयोगकर्ता को यह नहीं करना है। Iterators आंशिक रूप से एक पुस्तकालय का हिस्सा हैं।
कहा करने के बाद कि, यहाँ वास्तविक बदसूरत हिस्सा आता है:
अपनी खुद की iterators कुछ चीजें आप के बारे में पता करने की आवश्यकता है लिखने के लिए, यहाँ हैं सक्षम होने के लिए।
प्रकार लक्षण:
प्रकार लक्षण सी ++ जो प्रकार जो खुद को बदला नहीं जा सकता है के साथ भी काम करता है में प्रकार के aditional जानकारी जोड़ने के लिए एक सरल तंत्र हैं। उदाहरण के लिए एक पुनरावर्तक के लिए यह जानना महत्वपूर्ण है कि यह क्या हो रहा है (यानि निहित प्रकार)। दिए गए इटरेटर के लिए यह जानकारी प्राप्त करने का तरीका इटेटरेटर पर बहुत निर्भर करता है। वास्तव में ऑब्जेक्टर्स जो ऑब्जेक्ट्स हैं, आप कक्षा में टाइपिफ़ी जोड़ सकते हैं और उन का उपयोग कर सकते हैं, लेकिन इटरेटर जो पॉइंटर्स हैं, आपको पॉइंटर प्रकार से इसका अनुमान लगाने की आवश्यकता है। इसे संभव बनाने के लिए जानकारी को एक प्रकार की विशेषता में संग्रहीत किया जाता है, इसलिए एक ही स्थान एक कोड है जो इस जानकारी को देख सकता है। यह std::iterator_traits
प्रकार विशेषता है।
std::iterator_traits
किसी भी चीज़ पर काम करता है, जो std::iterator
टेम्पलेट के साथ-साथ किसी भी प्रकार के पॉइंटर पर बिना किसी ट्विकिंग के व्युत्पन्न होता है। अक्सर अपने खुद के लक्षण विशेषज्ञता लिखने से बचने के लिए std::iterator
आधार के रूप में उपयोग करना सबसे अच्छा है। यदि आप ऐसा नहीं कर सकते हैं, तो आवश्यक गुण प्रदान करना अभी भी संभव है, लेकिन यह कठिन होगा।
टैग वर्गों और इटरेटर प्रकार:
वहाँ सी में उपलब्ध iterators ++ जो अलग व्यवहार कर और/अलग अलग बातें की एक बहुत कुछ नहीं कर सकते कर सकते हैं के कई अलग अलग प्रकार के होते हैं। http://cplusplus.com/reference/std/iterator/ पर एक नज़र डालें, यह देखने के लिए कि किस प्रकार के इटरेटर उपलब्ध हैं और वे क्या कर सकते हैं। आरेख एक ऑब्जेक्ट उन्मुख तरीके से नहीं हैं (यानी input_iterator
न तो उप-न ही forward_iterator
का आधार वर्ग) है, बल्कि एक एपीआई प्रकार का व्युत्पन्न है। अर्थात। आप सभी एल्गोरिदम का उपयोग कर सकते हैं जो इनपुट इटरेटर के लिए एक आगे इटरेटर के साथ भी लिखे गए थे। पृष्ठ पर तालिका आपको बताएगी कि आपको प्रत्येक श्रेणी के लिए कौन सी विधियां प्रदान करनी होंगी।
चूंकि ये श्रेणियां वास्तव में एक-दूसरे के उप-वर्ग नहीं हैं (वे विशेष रूप से विभिन्न प्रकार के संग्रहों से आने पर नहीं होनी चाहिए), एक अन्य तंत्र का उपयोग प्रत्येक इटरेटर की क्षमताओं की पहचान के लिए किया जाता है। std::iterator_traits
में प्रत्येक इटेटरेटर का वर्णन करने वाला एक खाली टैग क्लास भी शामिल है, जो बताता है कि यह इटरेटर क्या कर सकता है और यह क्या नहीं कर सकता है। यदि आप अपने खुद के लक्षण नहीं लिखते हैं, तो आपको इस टैग क्लास को std::iterator
टेम्पलेट को तत्काल पर आपूर्ति करने की आवश्यकता है।
उदाहरण:
यह उदाहरण cplusplus से लिया जाता है।iterators पर कॉम अनुभाग:
class myiterator : public iterator<input_iterator_tag, int>
{
int* p;
public:
myiterator(int* x) :p(x) {}
myiterator(const myiterator& mit) : p(mit.p) {}
myiterator& operator++() {++p;return *this;}
myiterator operator++(int) {myiterator tmp(*this); operator++(); return tmp;}
bool operator==(const myiterator& rhs) {return p==rhs.p;}
bool operator!=(const myiterator& rhs) {return p!=rhs.p;}
int& operator*() {return *p;}
};
यह इटरेटर वास्तव में, मतलब नहीं है, क्योंकि यह केवल एक सूचक है, जो भी सीधे इस्तेमाल किया जा सकता गिर्द घूमती है। हालांकि यह एक स्पष्टीकरण के रूप में काम कर सकते हैं। इटेटरेटर उचित टैग की आपूर्ति करके से input_iterator
के रूप में लिया गया है। इसके अलावा टेम्पलेट को बताया गया है कि यह इटेटरेटर int
से अधिक है। अन्य सभी प्रकार, जिन्हें difference_type
, reference
, poiner
इत्यादि की आवश्यकता है, स्वचालित रूप से टेम्पलेट द्वारा इनके द्वारा ऑफ़र किया जाता है। कुछ मामलों में यह इन प्रकारों में से कुछ को मैन्युअल रूप से बदलने का अर्थ हो सकता है (उदाहरण के लिए std::shared_ptr
को कभी-कभी pointer
के रूप में उपयोग किया जाना चाहिए)। इसके अलावा इस इटरेटर के लिए आवश्यक लक्षण स्वचालित रूप से मौजूद होंगे, क्योंकि यह पहले से ही std::iterator
से लिया गया है और std::iterator_traits
पता है कि सभी आवश्यक जानकारी कहां मिलें।
सबसे आसान तरीका शायद 'iterator_facade' [Boost.Iterator] से (http://www.boost.org/doc/libs/release/libs/iterator/doc/iterator_facade.html) का प्रयोग है। –
बूस्ट :: फाइल सिस्टम का उपयोग करना और भी आसान कोड का उपयोग करना होगा ... –
ठीक है, मुझे पता होना चाहिए कि मुझे जानकारी जोड़नी चाहिए, कि मैं बूस्ट का उपयोग नहीं करना चाहता;) अधिकतर, क्योंकि मैं समझना चाहता हूं कि एक पुनरावर्तक कैसे काम करता है। – Ben