2017-01-26 14 views
7

मैंने उम्र बढ़ने का प्रयास करने की कोशिश की है कि यह क्यों हो रहा है।इस वस्तु को क्यों नष्ट नहीं किया जा रहा है?

struct Element 
    { 
     Element(int number) : number_ID(number) 
     { std::cout << "Element number " << number_ID << " is being constructed\n"; } 
     ~Element() 
     { std::cout << "Element number " << number_ID << " is being destroyed\n"; } 
     int number_ID; 
    }; 

    void createVector() 
    { 
     std::vector<Element> objArr; 
     objArr.reserve(10);  // So it doesn't have to reallocate 

     objArr.emplace_back(1); 
     objArr.emplace_back(2); 
     objArr.emplace_back(3); 
     objArr.emplace_back(4); 

     objArr.erase(objArr.begin());  // When I erase the first element only element 4 has destructor called 
    } 

    int main() 
    { 
     createVector(); 


     system("pause"); 
    } 

मैं:

Element number 1 is being constructed 
Element number 2 is being constructed 
Element number 3 is being constructed 
Element number 4 is being constructed 
//The following called when doing objArr.erase(objArr.begin()); 
Element number 4 is being destroyed 
//The following called after createVector() function exits 
Element number 2 is being destroyed 
Element number 3 is being destroyed 
Element number 4 is being destroyed 

एलिमेंट 1 के लिए नाशक कभी नहीं बुलाया जाता है? सबसे पहले मुझे नहीं पता था कि एलिमेंट नंबर 4 विनाशक को पहले तत्व को मिटाने के दौरान क्यों बुलाया जाएगा, और फिर मैंने सोचा कि जब यह अपने सदस्यों को बदल देता है तो शायद विनाशक को बुलाया जाना चाहिए। लेकिन दस्तावेज कहता है कि हटाए जाने के बाद सभी सदस्यों को स्थानांतरित कर दिया गया है, और 2 और 3 के विनाशकों को बुलाया नहीं गया था। मैं वास्तव में उलझन में हूँ।

संपादित करें: ठीक है अगर यह एक अनुकूलन कदम है, तो प्रलेखन है गलत है, क्योंकि:

वेक्टर से या तो एक एकल तत्व (स्थिति) या तत्वों की एक सीमा ([पहले निकालता है, पिछले))।

यह हटाए गए तत्वों की संख्या से कंटेनर आकार को प्रभावी ढंग से कम कर देता है, जो नष्ट हो जाते हैं।

यह तब नष्ट नहीं हो रहा है।

+0

आप पहले तत्व को मिटा देते हैं। खाली स्थान भरने के लिए बाएं को कॉपी/स्थानांतरित (असाइनमेंट द्वारा) प्राप्त करने वाले सभी तत्व। उसके बाद पूंछ तत्व नष्ट हो जाता है। यही वह है जो आप देखते हैं। – AnT

+0

@ एएनटी मुझे यह नहीं मिला, मैंने सोचा कि वेक्टर किसी भी विनाशकों को कॉल करने के लिए हमेशा सावधान रहना चाहता है, उदाहरण के लिए जब इसे पुन: आवंटित करना है तो सभी विनाशकों को कॉल करना होगा। तो अगर मुझे विनाशक की ज़रूरत है तो मुझे इसे खुद कॉल करने की ज़रूरत है? – Zebrafish

+1

लेकिन इस मामले में एक से अधिक विनाशक को कॉल करने की आवश्यकता नहीं है। कोई पुनर्वितरण नहीं है। और तत्वों को स्थानांतरित करना स्वाभाविक रूप से असाइनमेंट की श्रृंखला द्वारा हासिल किया जाता है। इसलिए, आपको इन पुनर्मूल्यांकनों के बाद पूंछ तत्व को नष्ट करना है। आप असाइनमेंट को विनाश के रूप में भी सोच सकते हैं जिसके बाद इसके एलएचएस का तत्काल निर्माण हो सकता है: आपको एलएचएस के पुराने मूल्य को नष्ट करना होगा और इसमें नया मूल्य बनाना होगा। इस अर्थ में, सभी शेष तत्वों को "विनाश" और "पुनः निर्मित" मिलता है। – AnT

उत्तर

14

vector प्रदर्शन को सहेजने की कोशिश कर रहा है।

erase क्या यह तत्व तत्व 2, 3 और 4 तत्वों को प्रतिबिंबित करता है, जिसमें 1 तत्व होता है। इसलिए पहले तत्व में अब 2 होता है, आदि। यह अंतिम तत्व को नष्ट कर देता है, जो कि 4 की एक प्रति है।

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

आपके vector में आपके द्वारा संग्रहीत प्रकार के आधार पर, यह पहले तत्व को नष्ट करने से पहले महंगा होगा, केवल पहले के संग्रहण में दूसरे तत्व की प्रतिलिपि बनाने के लिए।

...

यही तो नष्ट नहीं कर रहा है:

खैर अगर यह एक अनुकूलन कदम है, तो प्रलेखन गलत है, क्योंकि है।

दस्तावेज़ीकरण सही है, और यह उन्हें नष्ट कर रहा है।

आपकी ऑब्जेक्ट्स वे मान हैं जिनमें वे हैं। आपने घोषणा की कि आपकी कक्षाएं कॉपी करने योग्य हैं, इसलिए vector उन्हें कॉपी करने के लिए स्वतंत्र है। इसका मतलब है कि दो उदाहरणों के लिए एक ही मूल्य होने के लिए यह पूरी तरह से वैध है। vector इसका शोषण करता है।

यदि आपने अपनी कक्षाओं को गैर-प्रतिलिपि बना दिया है लेकिन आगे बढ़ने योग्य नहीं है, तो यह सही तरीके से काम करेगा। लेकिन आपके चालक कन्स्ट्रक्टर को स्थानांतरित वस्तु से बाहर निकलने की भी आवश्यकता होगी, ताकि कोई भी दो उदाहरण समान मूल्य न हो।

+0

पहला तत्व ओपनजीएल वीबीओ आईडी धारण कर रहा है, जिसे मुझे हटाना है, हे आदमी। – Zebrafish

+9

@TitoneMaurice: फिर आपकी कक्षा *** को कॉपी करने योग्य नहीं होना चाहिए! *** एक वर्ग जो प्रतिलिपि योग्य है वह एक वर्ग है जहां दो उदाहरणों का एक ही मूल्य हो सकता है, और आप एक से दूसरे के मानों को पारित कर सकते हैं। यह वही नहीं है जो आप चाहते हैं। [इस प्रकार आप ओपनजीएल ऑब्जेक्ट्स को एन्सेप्लेट करते हैं] (http://stackoverflow.com/documentation/opengl/7556/encapsulating-opengl-objects-with-c-raii#t=201701260337507343073) –

+0

मैन, मुझे लिखना चाहिए था सबूत बहुत लंबा लगेगा। ओह ठीक है: http://ideone.com/vlxlae – user4581301

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

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