2010-04-13 18 views
17

माफी माँगती है अगर सवाल मूर्खतापूर्ण लगता है, तो मैं एसओ में विशेषज्ञों का अनुसरण कर रहा था और कुछ उदाहरणों की कोशिश कर रहा था, और यह उनमें से एक है। मैंने खोज विकल्प का प्रयास किया लेकिन इस तरह के लिए कोई जवाब नहीं मिला।कक्षा के विनाशक को दो बार क्यों बुलाया जाता है?

class A 
{ 
    public: 
     A(){cout<<"A Contruction"<<endl;} 
     ~A(){cout<<"A destruction"<<endl;} 
}; 

int main() 
{ 
    vector<A> t; 
    t.push_back(A()); // After this line, when the scope of the object is lost. 
} 

कक्षा के विनाशक को दो बार क्यों बुलाया जाता है?

+0

ऐसा नहीं लगता कि SO ' 'टैग का समर्थन करता है। हालांकि, शायद मेटा पर एक सुविधा अनुरोध? मेथिंक जेफ इसे प्यार करने वाला है! :-) –

+0

@pst: धन्यवाद, मैं संपादन कर रहा था और इससे पहले कि मैं इसे बचा सकता था। – dicaprio

+5

बस सोच रहा है, यह समुदाय विकी क्यों है? – jasonline

उत्तर

39

तत्व जोड़ने के लिए एक अस्थायी वस्तु पर प्रतिलिपि बनाई गई है। push_back() के बाद अस्थायी वस्तु नष्ट हो जाती है - यह पहला विनाशक कॉल नहीं है। फिर vector उदाहरण दायरे से बाहर हो जाता है और संग्रहीत सभी तत्वों को नष्ट कर देता है - यह दूसरा विनाशक कॉल है।

+0

@ sharptooth और @Andreas: धन्यवाद। मैंने अभी आपका जवाब देखने के बाद कोशिश की, मैंने एक कॉपी कन्स्ट्रक्टर ए (कॉन्स्टा और) परिभाषित किया और हां इसे बुलाया गया। – dicaprio

+3

@dicaprio: निश्चित रूप से, जब तक आप अपनी खुद की प्रतिलिपि निर्माता को परिभाषित नहीं करते हैं, तब तक संकलक ने स्वचालित रूप से जेनरेट की गई प्रतिलिपि बनाई है। – sharptooth

4

विनाशक को एक बार बुलाया जाता है जब push_back पर अस्थायी रूप से भेजा जाता है और एक बार जब t में तत्व नष्ट हो जाता है।

19

यह तुम्हें दिखाता happening क्या:

struct A { 
    A() { cout << "contruction\n"; } 
    A(A const& other) { cout << "copy construction\n"; } 
    ~A() { cout << "destruction\n"; } 
}; 

int main() { 
    vector<A> t; 
    t.push_back(A()); 
} 
+0

! रोजर: मैंने इसे पोस्ट करने से ठीक पहले कोशिश की, मुझे अंक मिला, धन्यवाद !! – dicaprio

0

अधिकांश शायद, अपने वस्तु की प्रतिलिपि बनाई जा रही है। जिसके कारण, प्रतिलिपि-वस्तु के लिए विनाशक, और मूल-वस्तु के लिए कॉल-गिनती = 2 बनाता है।

उदाहरण: हालांकि, आप किसी वर्ग के ऑब्जेक्ट संदर्भ को पार कर रहे हैं, यह आंतरिक रूप से कॉपी-कन्स्ट्रक्टर का आह्वान करेगा। इससे बचने के लिए, बच्चे स्तरीय (जो करने के लिए आप माता पिता संदर्भ से गुजर रहे हैं, के रूप में होना चाहिए;

Parent *const &p parentRef; //Child.h 

फिर, माता पिता वस्तु के रूप में पारित हो जाएगा;

// Parent.cpp 
Parent *parentObj = this; 
Child *childObj = Child(parentObj); 

साथ ही, आप कर सकते हैं कॉपी-निर्माता invokation डिबग, अधिभावी द्वारा;

Parent(const Parent& object){ 
     cout <<"copy called.." << endl; 
} 
... 

अधिक जानकारी @[email protected]

1

दो विध्वंसक कॉल हैं क्योंकि दो ऑब्जेक्ट्स हैं: push_back पर तर्क, और vectort के भीतर नया जोड़ा गया तत्व।

STL containers स्टोर प्रतियां। आपके उदाहरण में vector में push_back द्वारा जोड़ा गया तत्व push_back पर दिए गए तर्क से निर्मित प्रतिलिपि है। तर्क A() है, जो एक अस्थायी वस्तु है, here (variant 4) देखें।

थोड़ा सा उत्तर विस्तारित करना, बिल्कुल आपने इसके लिए स्पष्ट रूप से पूछा है: अस्थायी नष्ट होने पर यह जानना उपयोगी हो सकता है। मानक (N4140) 12.2 p3 में बहुत स्पष्ट रूप से यह sais:

... अस्थायी वस्तुओं पूर्ण अभिव्यक्ति (1.9) कि (lexically) बिंदु शामिल हैं का मूल्यांकन करने में अंतिम चरण के रूप में नष्ट कर रहे हैं, जहां वे बनाए गए थे ...

साइड नोट: यदि आप emplace_back का उपयोग करते हैं तो केवल एक ही वस्तु होती है। कंटेनर में नया तत्व सीधे तर्कों से emplace_back में बनाया गया है। कई एसटीएल कंटेनर ने सी ++ 11 में एक इमस्थल संस्करण सीखा।

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

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