निम्नलिखित कोड नाशक 4 बार कॉल कॉल? मैं सोच रहा था कि केवल तीन विनाशक कॉल होना चाहिए।वापसी मूल्य अनुकूलन - - सी ++ नाशक
उत्तर
आपके कंपाइलर ने इसे अनुकूलित नहीं किया है। क्या आपने इसे ऑप्टिमाइज़ेशन सक्षम के साथ संकलित किया है?
यहाँ एक ही कोड के उत्पादन, जीसीसी के साथ संकलित है:
A
A
F
A
~A
~A
~A
main()
में दो वस्तुओं रहे हैं, तो नाशक सिर्फ उन्हें की वजह से दो बार बुलाया जाएगा। f()
में एक ऑब्जेक्ट, इसलिए विनाशक को इसके कारण एक कहा जाएगा। कुल 3 बार (जो आप उम्मीद करते हैं, लेकिन पढ़ते हैं ...)
अब चौथे समय विनाशक को f
से लौटने पर बनाई गई अस्थायी वस्तु के लिए बुलाया जाता है। ऐसा तब हो सकता है जब कोई आरवीओ न हो। आरवीओ कंपाइलर की पसंद है जिसका अर्थ है कि यह इसे अनुकूलित कर सकता है, या ऐसा नहीं हो सकता है। भाषा आरवीओ की कोई गारंटी नहीं देती है।
वैसे भी, बस अपना अनुकूलन स्तर बढ़ाएं; मुझे यकीन है कि आप केवल 3 विनाशक आमंत्रणों पर ही देखेंगे।
आप होने के लिए आरवीओ पर भरोसा नहीं कर सकते हैं। यही कारण है कि आपको कभी भी विनाशकों के अंदर कार्यात्मक तर्क नहीं देना चाहिए या रचनाकारों की प्रतिलिपि बनाना चाहिए (हां, उनको भी elided किया जा सकता है)।
रिटर्न वैल्यू ऑप्टिमाइज़ेशन मानक की अनुमति देता है, लेकिन लागू नहीं होता है।
कोई अनुकूलन या ओ 2 के साथ, मुझे भी 4 विनाशक कॉलसे मिलती है।
पूर्ण अनुकूलन के साथ- बैल - मैं केवल मिल 3.
/O2 में एनआरवीओ भी शामिल है, जिसका अर्थ है कि केवल 3 विनाशक कहा जाता है। Http://msdn.microsoft.com/en-us/library/8f8h5cxt.aspx देखें। – LihO
@LihO मैंने कोड का परीक्षण किया। तो मुझे लगता है कि एमएसवीएस में एक बग है, अगर आप जो कहते हैं वह सटीक है। –
मैंने इसका परीक्षण भी किया (एमएसवीएस -2010)। अनुकूलन अक्षम ('/ ओडी') के साथ 4 विनाशक कहा जाता है। '/ O1' या'/O2' के साथ, 3 विनाशक कहा जाता है। – LihO
वहाँ एक छिपे हुए निर्माण और A
का एक उदाहरण के विनाश है: जब आप समारोह f()
से वापस लौट रहे हैं, वस्तु b
की अस्थायी प्रतिलिपि बनाई गई है। इसे को main()
में सौंपा गया है और फिर नष्ट कर दिया गया है।
वह पूछ रहा है कि आरवीओ क्यों नहीं होता है। –
@ लचियन आप सही हैं, लेकिन उन्होंने ऑप्टिमाइज़ेशन स्तर का उपयोग नहीं किया है (या नहीं), मैं इंप्रेशन के तहत था कि उसने मूल्य से लौटने पर अस्थायी रूप से अनदेखा किया था। –
f
में स्थानीय चर को फ़ंक्शन लौटने पर अस्थायी चर में कॉपी किया गया है। यही कारण है कि चार विनाशक कॉल हैं। (प्रतिलिपि बनाने का कार्य नहीं अपने डिफ़ॉल्ट निर्माता A()
, इसलिए तीन A
रों प्रतिलिपि निर्माता A(A&)
कहता है।)
यह सवाल नहीं है। वह पूछ रहा है कि वापसी मूल्य अनुकूलन क्यों लागू नहीं होता है। –
मुझे यकीन नहीं है कि उसे आरवीओ के बारे में भी पता है। सवाल यह है कि "तीन की बजाय चार विनाशक कॉल क्यों हैं?" मैंने जवाब दिया। –
क्या आपने शीर्षक पढ़ा है? –
मुख्य में 2 वस्तुओं के होते हैं: A a,b;
, समारोह f()
के शरीर में एक वस्तु: A b;
और फिर वहाँ अस्थायी वस्तु है कि कॉपी किया जा रहा है और इसकी प्रति b
में संग्रहीत है।
जब आपके समारोह के मुख्य भाग में b
लौटने, प्रतिलिपि पहली बार में बनाया जाता है, तो स्थानीय b
विलुप्त है, तो मुख्य में घोषित कर दिया और उसके बाद इस प्रति विलुप्त है चर b
में कॉपी असाइन किया गया है।
जोड़ें वर्ग A
परिभाषा करने के लिए लाइन के बाद और अपने आप को देखें:
A(const A&) { cout << "copying" << endl; }
Named Return Value Optimization साथ
, संकलक अनावश्यक कॉपी निर्माता को खत्म करने की कोशिश करता है और नाशक जिसका अर्थ है कि स्थानीय b
समारोह f()
से आवंटित किया जाएगा कॉल प्रतिलिपि बनाये बिना मुख्य में b
परिवर्तनीय में। इसलिए आरवीओ/एनआरवीओ के साथ केवल 3 ऑब्जेक्ट्स आपके मामले में बनाए जाते हैं।
हालांकि एक तरह से अपने मामले में RVO बिना इस प्रति destructing से बचने के लिए कैसे है:
A a;
A b = a.f();
समारोह
f()
की वापसी मान के इस मामले के पिछले भाग में
बनाया है और एक चर b
के रूप में जमा है। जिसका अर्थ है कि कोई भी अभिसरण ऑपरेटर नहीं कहा जाता है और केवल 2 ऑब्जेक्ट मुख्य रूप से बनाए जाते हैं: a
और b
की प्रति f()
द्वारा लौटा दी गई है।
उम्मीद है कि इससे मदद मिलती है।
नहीं, ऐसा नहीं है। http://ideone.com/ywGdo –
ओह! मैंने कोडपैड का उपयोग किया .. http://codepad.org/1OJGoYGP – Venky
सी ++ के बारे में होने पर अपने प्रश्नों को "सी" से टैग न करें। भाषाएं समान नहीं हैं। – tinman