दिलचस्प पोस्ट
स्टोरीबोर्ड में टेबल हैडर दृश्य पायथन में मेटाक्लास क्या है? वर्तमान क्लिपबोर्ड सामग्री प्राप्त करें? एक अलग वर्ग से कई जेबटन क्रियाओं को कैसे परिभाषित किया जाए Android डिवाइस पर विश्वसनीय सीए प्रमाण पत्र कैसे स्थापित करें? अपाचे स्पार्क वेब यूआई में "स्टेज स्किप" का क्या मतलब है? डबल चेक किए गए लॉकिंग के इस उदाहरण में अस्थिर का उपयोग क्यों किया जाता है HttpURLConnection से InputStream ऑब्जेक्ट प्राप्त करते समय FileNotFoundException मैक ओएस एक्स 10.6.4 पर अजगर 2.7 की स्थापना कैसे करें? जेएसपी में ईएल के भाव का मूल्यांकन नहीं किया गया निर्धारित बिंदु गणित करने का सबसे अच्छा तरीका क्या है? PHP क्लास के तरीकों में अग्रणी अंडरस्कोर के साथ क्या सौदा है? जावा कन्स्ट्रक्टर्स डिबग मोड के लिए इस निष्पादन योग्य के लिए एक वैध प्रावधान प्रोफ़ाइल नहीं मिली ओरेकल में मिलीसेकंड में दो टाइमस्टैम्प के बीच अंतर की गणना करना

सी ++ में अस्थायी जीवनभर की गारंटी है?

क्या सी ++ एक अस्थायी चर के जीवनकाल के लिए गारंटी प्रदान करता है जो फ़ंक्शन कॉल के भीतर बनाई जाती है लेकिन पैरामीटर के रूप में इसका उपयोग नहीं किया जाता है? यहां एक उदाहरण वर्ग है:

class StringBuffer { public: StringBuffer(std::string & str) : m_str(str) { m_buffer.push_back(0); } ~StringBuffer() { m_str = &m_buffer[0]; } char * Size(int maxlength) { m_buffer.resize(maxlength + 1, 0); return &m_buffer[0]; } private: std::string & m_str; std::vector<char> m_buffer; }; 

और यहां बताया गया है कि आप इसका उपयोग कैसे करेंगे:

 // this is from a crusty old API that can't be changed void GetString(char * str, int maxlength); std::string mystring; GetString(StringBuffer(mystring).Size(MAXLEN), MAXLEN); 

अस्थायी स्ट्रिंगबफर ऑब्जेक्ट के लिए डिस्ट्रिक्टर कब बुलाएगा? क्या यह:

  • GetString को कॉल करने से पहले?
  • GetString रिटर्न के बाद?
  • कंपाइलर निर्भर?

मुझे पता है कि C ++ की गारंटी देता है कि स्थानीय अस्थायी चर मान्य होगा जब तक कि इसका कोई संदर्भ है – क्या यह पैरेंट ऑब्जेक्ट पर लागू होता है जब एक सदस्य चर का संदर्भ होता है?

धन्यवाद।

वेब के समाधान से एकत्रित समाधान "सी ++ में अस्थायी जीवनभर की गारंटी है?"

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

यह वास्तव में अभिव्यक्ति टेम्पलेट्स का काम करता है: वे इस प्रकार के अस्थायी लोगों के संदर्भ को ऐसे अभिव्यक्ति में रख सकते हैं जैसे

 e = a + b * c / d 

क्योंकि हर अस्थायी अभिव्यक्ति तक चलेगा

 x = y 

का मूल्यांकन पूरी तरह से किया गया है यह मानक में 12.2 Temporary objects में संक्षिप्त रूप से वर्णित है।

litb का उत्तर सटीक है अस्थायी ऑब्जेक्ट (भी एक rvalue के रूप में जाना जाता है) के जीवनकाल अभिव्यक्ति से जुड़ा हुआ है और अस्थायी ऑब्जेक्ट के लिए डिस्ट्रक्टर पूर्ण अभिव्यक्ति के अंत में कहा जाता है और जब स्ट्रिंगबफर पर डिस्ट्रक्टर कहलाता है, एम_बफर पर डिस्ट्रक्टर भी होगा कहा जाता है, लेकिन m_str पर विध्वंसक नहीं है क्योंकि यह एक संदर्भ है।

ध्यान दें कि C ++ 0x कुछ ही चीज़ों को बदलता है क्योंकि यह रैवल्यू संदर्भों को जोड़ता है और शब्दों को स्थानांतरित करता है अनिवार्य रूप से एक rvalue संदर्भ पैरामीटर (&& के साथ दिये गये) का उपयोग करके मैं फ़ंक्शन में रॉल्यूव 'ले जा सकता हूं' (इसे कॉपी करने के बजाय) और रवाइव का जीवनकाल उस ऑब्जेक्ट के लिए बाध्य किया जा सकता है जो अभिव्यक्ति में नहीं चलता है एमएसवीसी टीम से एक बहुत अच्छा ब्लॉग पोस्ट है जो उस पर बहुत विस्तार से चलता है और मैं इसे लोगों को पढ़ने के लिए प्रोत्साहित करता हूं।

चलती रैवल्यू के लिए शैक्षणिक उदाहरण अस्थायी स्ट्रिंग हैं और मैं एक कन्स्ट्रक्टर में असाइनमेंट दिखाऊंगा। अगर मेरे पास एक क्लास मायटाइप है जिसमें एक स्ट्रिंग सदस्य चर है, तो इसे इस तरह से आरंभीकृत किया जा सकता है जैसे कि कन्स्ट्रक्टर में:

 class MyType{ const std::string m_name; public: MyType(const std::string&& name):m_name(name){}; } 

यह अच्छा है क्योंकि जब मैं एक अस्थायी ऑब्जेक्ट के साथ इस क्लास का एक उदाहरण घोषित करता हूं:

 void foo(){ MyType instance("hello"); } 

क्या होता है कि हम अस्थायी ऑब्जेक्ट को कॉपी और नष्ट करने से बचाते हैं और "हैलो" को मालिक वर्ग के सदस्य चर में सीधे रखा जाता है यदि ऑब्जेक्ट 'स्ट्रिंग' से भारी वजन है तो अतिरिक्त कॉपी और डिस्ट्रिक्टर कॉल महत्वपूर्ण हो सकता है

GetString रिटर्न के लिए कॉल करने के बाद

मैंने लगभग उसी वर्ग को लिखा था:

 template <class C> class _StringBuffer { typename std::basic_string<C> &m_str; typename std::vector<C> m_buffer; public: _StringBuffer(std::basic_string<C> &str, size_t nSize) : m_str(str), m_buffer(nSize + 1) { get()[nSize] = (C)0; } ~_StringBuffer() { commit(); } C *get() { return &(m_buffer[0]); } operator C *() { return get(); } void commit() { if (m_buffer.size() != 0) { size_t l = std::char_traits<C>::length(get()); m_str.assign(get(), l); m_buffer.resize(0); } } void abort() { m_buffer.resize(0); } }; template <class C> inline _StringBuffer<C> StringBuffer(typename std::basic_string<C> &str, size_t nSize) { return _StringBuffer<C>(str, nSize); } 

मानक से पहले प्रत्येक कंपाइलर ने इसे अलग तरह से किया था। मेरा मानना ​​है कि सी ++ के लिए पुराने एन्टेटेड रेफरेंस मैनुअल ने निर्दिष्ट किया कि अस्थायी लोगों को दायरे के अंत में साफ करना चाहिए, इसलिए कुछ कंपाइलर ने ऐसा किया। 2003 के अंत तक, मुझे पता चला कि व्यवहार अभी भी सूर्य के बलशाली सी ++ कंपाइलर पर मौजूद था, इसलिए स्ट्रिंगबफर काम नहीं कर रहा था। लेकिन मुझे आश्चर्य होगा कि यदि कोई भी मौजूदा संकलक अभी भी टूट गया था।

स्ट्रिंगबफर गेटस्ट्रिंग के दायरे में है इसे GetString के दायरे के अंत में नष्ट करना चाहिए (यानी जब यह रिटर्न) इसके अलावा, मुझे विश्वास नहीं है कि सी ++ की गारंटी होगी कि जब तक संदर्भ होता है तब तक एक चर मौजूद होगा।

निम्नलिखित संकलन करना चाहिए:

 Object* obj = new Object; Object& ref = &(*obj); delete obj;