2016-08-18 6 views
5

मुझे इस बारे में अधिक जानकारी नहीं मिल रही है कि क्या Iterators अंतर्निहित वस्तु को पकड़ते हैं या नहीं।क्या सी ++ इटरेटर्स अंतर्निहित वस्तु का संदर्भ रखते हैं?

यदि मैं एक इटरेटर बना देता हूं, तो ऑब्जेक्ट जो इसे प्रदान करता है वह गुंजाइश से बाहर हो जाता है, क्या इटरेटर की उपस्थिति इसे नष्ट होने से रोकती है?

// This class takes a copy of iterators to use them later 
class Data { 
    public: 
    Data(std::vector<int>::iterator start, std::vector<int>::iterator end) 
     : start(start), 
     end(end) 
    {} 

    void show() { 
     // Use this->start and this->end for some purpose 
    } 

    private: 
    std::vector<int>::iterator start; 
    std::vector<int>::iterator end; 
}; 

Data test() { 
    std::vector<int> v{1, 2, 3}; 
    Data d(v.begin(), v.end()); 
    d.show(); // this would be ok 
    return d; 
} 

int main(void) { 
    Data d = test(); 
    d.show(); // What happens here? 
} 

इस उदाहरण में, Data वस्तु iterators की एक प्रति है, जो पहली show() कॉल के लिए ठीक है भंडारण किया जाता है:

यहाँ एक बहुत ही सरल उदाहरण सिर्फ परिदृश्य वर्णन करने के लिए है। हालांकि दूसरे show() कॉल के समय तक, मूल ऑब्जेक्ट जो इटरेटर की आपूर्ति करता है अब मौजूद नहीं है।

क्या इटेटरेटर ऑब्जेक्ट को तब तक रखते हैं जब तक कि वे सभी स्वयं नष्ट नहीं हो जाते हैं, या जैसे ही मूल वस्तु गुंजाइश से बाहर हो जाती है?

यहाँ one reference of many जो नहीं कहना है क्या एक ही रास्ता या अन्य होता है (या यहां तक ​​कि क्या इसी का परिणाम 'अनिर्धारित' है।)

+7

इटरेटर पॉइंटर्स पर मॉडलिंग किए जाते हैं। असल में, यदि कोई सूचक उच्च स्तर की चीज एक्स नहीं कर सकता है, तो न तो इटरेटर कर सकते हैं। –

+0

हां, इटरेटर को अमान्य कर दिया जाएगा, परिणाम अपरिभाषित है। – songyuanyao

+1

अपनी विशिष्ट स्थिति को हल करने के लिए: एक कंटेनर को नष्ट करना सभी इटरेटर को अमान्य करता है। –

उत्तर

5

इटरेटर्स आमतौर पर उस डेटा का स्वामित्व नहीं रखते जिस पर वे पुन: प्रयास करते हैं, नहीं। वास्तव में, वे शायद ही कभी (0 कभी भी) डेटा के मालिक के ऑब्जेक्ट के से अवगत हैं; वेक्टर इटरेटर, उदाहरण के लिए, अक्सर पॉइंटर्स होते हैं, जिन्हें किसी भी वेक्टर या उसके जीवनकाल का कोई ज्ञान नहीं है। यहां तक ​​कि उन इटरेटर्स जिन्हें पॉइंटर्स के रूप में लागू नहीं किया जाता है (जो उनमें से अधिकतर है) को "सूचक" के रूप में माना जा सकता है, और इस तरह व्यवहार किया जाता है: वे आसानी से खतरनाक हो सकते हैं।

आपके उदाहरण में यूबी है क्योंकि आप दूसरी बार show() के अंदर अमान्य iterators को अस्वीकार कर देंगे।

यदि आपका कंटेनर दायरे से बाहर हो जाता है तो आपके सभी इटरेटर अवैध हो जाते हैं। वास्तव में, there are all manner of reasons why an iterator may become invalidated, जैसे वेक्टर में जोड़ना जब उस ऑपरेशन के परिणामस्वरूप क्षमता विस्तार होता है।

यह बजाय कुछ संग्रह (जैसे Boost's counting iterators के रूप में) कहीं भी पाई अधिक पुनरावृत्ति की, iterators कि "स्वयं" डेटा तरह कर खोजने के लिए संभव है, लेकिन इन जादुई गुणों कि सी ++ का लाभ लेने के एक जादुई समारोह प्रदान करने के लिए कर रहे हैं, सी ++ द्वारा परिभाषित किए गए इटरेटर्स की अंतर्निहित संपत्ति नहीं है।

2

एक इटरेटर आम तौर पर केवल अपने मूल रूप में लंबे समय के रूप में मान्य है कंटेनर या "अनुक्रम" को बदला नहीं गया है, क्योंकि एक बदलाव मेमोरी रीयलोकेशन और मेमोरी चाल का कारण बन सकता है। चूंकि इटेनेटर आमतौर पर संदर्भ मेमोरी मूल कंटेनर में, कहा गया कंटेनर में एक परिवर्तन इटेटरेटर को अमान्य कर सकता है।

अब, एक कंटेनर जो दायरे से बाहर निकलता है उसे इसके विनाशक को निष्पादित किया जाता है। यह स्पष्ट रूप से कंटेनर को बदल देगा और इसलिए इसे किसी भी इटरेटर को प्रक्रिया में अमान्य कर दिया जाएगा।

1

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

दूसरा, जब आपका कंटेनर नष्ट हो जाता है (और यह तब होता है जब यह दायरे से बाहर हो जाता है), कंटेनर में सभी वस्तुओं को भी नष्ट किया जा रहा है। इस प्रकार, कंटेनर नष्ट होने के बाद इटेटरेटर अमान्य हो जाता है। उस वृद्धि के बाद, पुनरावर्तक और पुनरावर्तक को पुन: कॉन्फ़्रेंस करने से अपरिभाषित व्यवहार होगा।

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