गलत फॉर्म:
int &z = 12;
ठीक रूप:
int y;
int &r = y;
प्रश्न :
पहला कोड गलत क्यों है? शीर्षक में त्रुटि का" अर्थ "क्या है?
गलत फॉर्म:
int &z = 12;
ठीक रूप:
int y;
int &r = y;
प्रश्न :
पहला कोड गलत क्यों है? शीर्षक में त्रुटि का" अर्थ "क्या है?
(ostringstream() << "x=" << x).str()
जवाबों:
C ++ 03 3.10 / 1 कहता है: "हर अभिव्यक्ति या तो एक लवलीन या एक लकीर है।" यह याद रखना महत्वपूर्ण है कि प्रफुल्लता बनाम प्रगाढ़ता भावों का गुण है, वस्तुओं का नहीं।
Lvalues उन वस्तुओं को नाम देते हैं जो एकल अभिव्यक्ति से परे बनी रहती हैं। उदाहरण के लिए, obj
, *ptr
, ptr[index]
, और ++x
सभी lvalues हैं।
अंतराल अस्थायी हैं जो पूर्ण अभिव्यक्ति के अंत में वाष्पित होते हैं जिसमें वे रहते हैं ("अर्धविराम पर")। उदाहरण के लिए, 1729
, x + y
, std::string("meow")
, और x++
सभी rvalues हैं।
ऑपरेटर के पते के लिए आवश्यक है कि इसका "ऑपरेंड एक अंतराल होगा"। अगर हम एक अभिव्यक्ति का पता ले सकते हैं, तो अभिव्यक्ति एक लवल्यू है, अन्यथा यह एक लकीर है।
&obj; // valid
&12; //invalid
int & = 12;
अमान्य क्यों है, मानक का कहना है कि एक स्ट्रिंग शाब्दिक एक अंतराल है, अन्य शाब्दिक हैं।
std::string("meow")
एक प्रकार की वस्तु का निर्माण करता है std::string
और एक ऐसा पैदावार देता है जो इस ऑब्जेक्ट को नामित करता है, 1729
जिसका कोई साइड-इफ़ेक्ट नहीं है और इसकी वैल्यू है। 1729 प्रकार के एक प्रतिद्वंद्विता के रूप में int
।
"Lvalues name objects that persist beyond a single expression."
100% सही कथन है। इसके विपरीत, आपका उदाहरण (const int &)1
गलत है, क्योंकि यह "नाम" ऑब्जेक्ट नहीं है।
int &z = 12;
दाहिने हाथ की ओर, एक प्रकार की अस्थायी वस्तु int
अभिन्न शाब्दिक से बनाई गई है 12
, लेकिन अस्थायी गैर-कब्जे संदर्भ के लिए बाध्य नहीं हो सकती है। इसलिए त्रुटि। यह समान है:
int &z = int(12); //still same error
एक अस्थायी क्यों बनाया जाता है? क्योंकि किसी संदर्भ में मेमोरी में किसी ऑब्जेक्ट का उल्लेख होता है, और किसी ऑब्जेक्ट के अस्तित्व के लिए, इसे पहले बनाना पड़ता है। चूँकि वस्तु अनाम है, यह एक अस्थायी वस्तु है। इसका कोई नाम नहीं है। इस स्पष्टीकरण से, यह बहुत स्पष्ट हो गया कि दूसरा मामला ठीक क्यों है।
एक अस्थायी ऑब्जेक्ट कॉन्स्ट रेफरेंस के लिए बाध्य हो सकता है, जिसका अर्थ है, आप यह कर सकते हैं:
const int &z = 12; //ok
पूर्णता के लिए, मैं जोड़ना चाहूंगा कि C ++ 11 ने व्याप्त-संदर्भ प्रस्तुत किया है, जो अस्थायी वस्तु को बांध सकता है। तो C ++ 11 में, आप इसे लिख सकते हैं:
int && z = 12; //C+11 only
ध्यान दें कि वहाँ का &&
इरादा है &
। यह भी ध्यान दें कि const
अब इसकी आवश्यकता नहीं है, भले ही वह वस्तु जो z
बांधती है, एक अस्थायी वस्तु है जो अभिन्न-शाब्दिक रूप से बनाई गई है 12
।
चूंकि C ++ 11 ने व्याप्त-संदर्भ प्रस्तुत किया है , int&
इसलिए अब इसे lvalue-reference कहा जाता है ।
12
एक संकलन-समय स्थिर है जिसे संदर्भित डेटा के विपरीत नहीं बदला जा सकता है int&
। तुम क्या कर सकते हो
const int& z = 12;
void f( vector<int> const & )
, जो एक वेक्टर पास करने के लिए मुहावरेदार है जिसे संशोधित नहीं किया जाना है। अब समस्या यह है कि f( vector<int>(5) )
यह गलत होगा, और उपयोगकर्ता को एक अलग अधिभार प्रदान करना होगा void f( vector<int> v ) { f(v); }
जो कि तुच्छ हो।
f( vector<int>(5) )
, कंपाइलर एक अस्थायी बनाता है और फिर उस अस्थायी के संदर्भ को बांधता है, और इसी तरह अगर 5
प्रत्यक्ष रूप से निहित रूपांतरण था । यह संकलक को फ़ंक्शन के लिए एक हस्ताक्षर बनाने की अनुमति देता है और फ़ंक्शन के एकल उपयोगकर्ता कार्यान्वयन को सक्षम करता है। वहाँ से, समान व्यवहार को स्थिरता के लिए निरंतर संदर्भों के उपयोग के लिए परिभाषित किया गया है।
T const & r = *ptr;
किसी भी बाद के उपयोग को r
प्रतिस्थापित किया जा सकता है *ptr
, और r
रनटाइम पर मौजूद होने की आवश्यकता नहीं है) या इसे उस ऑब्जेक्ट का पता रखकर लागू किया जा सकता है जो इसे उपनाम देता है (किसी ऑब्जेक्ट के सदस्य के रूप में एक संदर्भ को संग्रहीत करने पर विचार करें) - जो ऑटोडेरेफेरड पॉइंटर के रूप में लागू किया जाता है।
ये C ++ भाषा के नियम हैं:
12
) एक "लकीर" हैint &ri = 12;
बीमार हैआपको यह समझना होगा कि ये C ++ नियम हैं। वे बस हैं।
सी ++ ', एक अलग भाषा का आविष्कार करना आसान है, थोड़ा अलग नियमों के साथ। C ++ 'में, यह एक नॉन-कॉस्ट रेफ़रेंस के साथ बनाने की अनुमति होगी। यहाँ कुछ भी असंगत या असंभव नहीं है।
लेकिन यह कुछ जोखिम भरे कोड की अनुमति देगा जहां प्रोग्रामर को वह नहीं मिल सकता है जो वह चाहता था, और सी ++ डिजाइनरों ने सही तरीके से उस जोखिम से बचने का फैसला किया।
संदर्भ उन चीजों के लिए "छिपे हुए संकेत" (गैर-अशक्त) हैं जो बदल सकते हैं (lvalues)। आप उन्हें एक निरंतरता के लिए परिभाषित नहीं कर सकते। यह एक "परिवर्तनशील" चीज होनी चाहिए।
संपादित ::
मैं सोच रहा हूं
int &x = y;
लगभग बराबर
int* __px = &y;
#define x (*__px)
__px
एक नया नाम कहां है, और #define x
केवल x
संदर्भ की घोषणा वाले ब्लॉक के अंदर काम करता है ।
const
:)
const