2012-10-18 14 views
7

मैं एक नहीं बल्कि बुनियादी सी ++ सवाल मिल गया है, कि नीचे एक की तरह उन मापदंडों से एक समारोह है कि कुछ इनपुट पैरामीटर लेता है और बनाता है एक std::string पर विचार करें:सी ++ लौटने अस्थायी वस्तुओं भ्रम

std::string constructString(int some_parameter) { 

    std::stringstream ss; 

    // Construct a string (arbitrarily complex) 
    ss << "Some parameter is " << some_parameter << " right now"; 

    return ss.str(); //Am I not returning a temporary object here? 
} 

मुझे लगता है कि समझ में फ़ंक्शन लौटने पर स्ट्रिंगस्ट्रीम-ऑब्जेक्ट गुंजाइश से बाहर हो जाएगा, लेकिन क्या यह निर्मित स्ट्रिंग को भी अमान्य नहीं करता है?

क्या होगा यदि मैंने वापसी प्रकार को const char * पर बदल दिया और इसके बजाय ss.str().c_str() लौटा दिया?

उपरोक्त की तरह कोड काम करता प्रतीत होता है, लेकिन मुझे संदेह है कि ऐसा इसलिए है क्योंकि 'अस्थायी' ऑब्जेक्ट वाली मेमोरी अभी तक किसी अन्य चीज़ के साथ ओवरराइट नहीं हुई है जब मैं इसका उपयोग करता हूं?

मुझे स्वीकार करना है, मैं सामान्य रूप से ऐसी परिस्थितियों में उलझन में हूं, अगर कोई इस पूरे "अस्थायी वस्तुओं" को समझा सकता है (या बस मुझे सही दिशा में इंगित करता है) तो मैं इसकी सराहना करता हूं।

अग्रिम

उत्तर

10

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

आप const char * को वापसी प्रकार बदल सकते हैं और ss.str().c_str() वापसी यदि आप ss.str() द्वारा लौटाए गए अस्थायी std::string के कुछ बफर करने के लिए सूचक वापसी होगी और है कि बुरा होगा।

2

जैसा कि आप देखते हैं Stringstream::str()std::string ऑब्जेक्ट देता है। आप संदर्भ के बिना std::string लौटाते हैं जिसका अर्थ है कि आरवीओ (एनआरवीओ) ऑप्टिमाइज़ेशन कॉपी कन्स्ट्रक्टर बिना कॉल 0 औरऑब्जेक्ट को वैध बनाएगा। ऑप्टिमाइज़ेशन std::string के साथ कॉपी कन्स्ट्रक्टर के बिना स्थानांतरित किया जाएगा। लेकिन अगर std::string& वापस आ जाएगा तो यह क्रैश हो जाएगा क्योंकि फ़ंक्शन रिटर्न के बाद यह ऑब्जेक्ट नष्ट हो जाएगा। उसी प्रभाव const char * के साथ होगा क्योंकि इस सूचक को नष्ट करने के बाद खराब स्मृति पर संकेत मिलेगा और यह खतरनाक स्थिति है।

+0

इस प्रतिलिपि को फ़ंक्शन कॉलिंग निर्माण स्ट्रिंग द्वारा उठाए जाने के बाद बुलाया जाएगा विनाशक? चूंकि यह अस्थायी वस्तु है, मुझे लगता है कि इसे पॉइंटर को स्टैक पर वापसी मूल्य के रूप में रखा जाता है। लौटने के बाद क्या होता है? यदि कोई नया ऑब्जेक्ट स्वामी नहीं है तो क्या यह नष्ट हो गया है? कैसे संकलक जानता है कि ऑब्जेक्ट को नष्ट करना है या वापस लौटने के बाद नहीं? –

1

यह मान लें: T val = some_function(), जब आप some_function सी ++ मूल्य प्रतिलिपि मूल्य का मूल्य val में निर्दिष्ट प्रतिलिपि निर्माता या अंतर्निर्मित ऑपरेटर का उपयोग करते हुए मान वापस करते हैं। तो यदि आप int या std::string वापस लौटते हैं तो कोई समस्या नहीं है, लेकिन यदि आप एक स्मृति में एक सूचक लौटाते हैं जो फ़ंक्शन के अंत में मुक्त हो जाएगा, ओह !! आपके सूचक को एक अवैध स्मृति की ओर इशारा किया जाएगा। उदाहरण के लिए इस पर विचार करें:

const char* some_function() { 
    std::string res(...); 
    //... 
    return res.c_str(); 
} 

आप डेटा है कि समारोह वापसी के रूप में जैसे ही मुक्त हो जाएगा (क्योंकि res नष्ट हो जाएगा और वह अपने आंतरिक डेटा मुक्त होगा) पता है ताकि आप मिल जाएगा करने के लिए सूचक लौट रहे हैं, लेकिन यह है कि पता आपको इंगित नहीं करता कि आप क्या उम्मीद कर सकते हैं!

+0

* "सी ++ वैल्यू में लौटाए गए मूल्य का प्रति मान" * - इससे भी अधिक, यह पहले से ही फ़ंक्शन के रिटर्न वैल्यू में 'ss.str()' द्वारा लौटाए गए मान की प्रतिलिपि बनाता है, क्योंकि वह मूल्य-दर देता है। तो यह 'const_function' रिटर्न बाय-वैल्यू के साथ 'कॉन्स्ट टी एंड वैल = some_function()' के साथ भी काम करेगा। –

+1

'कॉन्स्ट टी एंड वैल = some_function() 'वास्तव में पूरी तरह से काम करता है, क्योंकि सी ++ मूल्य से प्रत्येक चीज की प्रतिलिपि बनाता है और' कॉन्स्ट टी एंड 'वास्तव में कुछ अलग अर्थपूर्ण के साथ' कॉन्स्ट टी * 'है, यहां समस्या एक स्थान पर' कॉन्स्ट टी एंड 'बिंदु है फ़ंक्शन कॉल पूर्ण होने के बाद इसे अमान्य कर दिया जाएगा! – BigBoss

+1

नहीं, ऐसा नहीं होगा, क्योंकि एक अस्थायी के लिए एक कॉन्स्ट संदर्भ बाध्यकारी अस्थायी जीवनकाल बढ़ाता है। यही कारण है कि 'शून्य फू (कॉन्स std :: स्ट्रिंग और); foo ("test"); 'पूरी तरह से ठीक काम करता है। यह एक सूचक (या एक गैर-कॉन्स्ट संदर्भ) के लिए काम नहीं करेगा, हालांकि। यह छोटे अंतरों में से एक है, जो वास्तव में संकेतकों के लिए वाक्य रचनात्मक चीनी से कुछ और संदर्भ बनाते हैं। –

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