2010-02-23 40 views
9

में संदर्भ प्रारंभिकरण क्या कोई मुझे बता सकता है कि इन दो बयानों के बीच कोई अंतर क्यों है?सी ++

class A{}; 

const A& a = A();   // correct 

A& b = A();    // wrong 

इसे कहते हैं प्रकार A

की एक अस्थायी से प्रकार A& के गैर स्थिरांक संदर्भ की अमान्य आरंभीकरण क्यों बात यहाँ const करता है?

उत्तर

14

गैर-कॉन्स संदर्भों को एल-मानों के साथ प्रारंभ किया जाना चाहिए। यदि आप उन्हें अस्थायी के साथ शुरू कर सकते हैं, तो निम्नलिखित क्या करेंगे?

int& foo = 5; 
foo = 6; // ?! 

const संदर्भ विशेष गुण है कि वे रेफरी के जीवन का विस्तार है, और क्योंकि वे const हैं, वहाँ कोई संभावना नहीं है कि आप कुछ है कि स्मृति में बैठने नहीं है संशोधित करने के लिए कोशिश करता हूँ है। उदाहरण के लिए:

const int& foo = 5; 
foo = 6; // not allowed, because foo is const. 

याद रखें कि संदर्भ वास्तव में कुछ नहीं, अस्थायी चर का उल्लेख किया है। उदाहरण के लिए, निम्नलिखित मान्य है:

int foo = 5; 
int& bar = foo; 
bar = 6; 
assert(foo == 6); 
+1

रुको, तो क्या इसका मतलब है कि मैं 'कॉन्स्ट क्लास ए और रेफरी = रिटर्न्स क्लासएबीवैल्यू();' का उपयोग कर सकता हूं? मैंने सोचा कि अस्थायी अगली पंक्ति पर मर जाएगी। – Lucas

+2

हां, आप इसका उपयोग कर सकते हैं। जब तक संदर्भ चर करता है तब तक अस्थायी रहेगा: http://herbsutter.spaces.live.com/blog/cns!2D4327CC297151BB!378.entry –

+1

बहुत बढ़िया, धन्यवाद। SO पर, आप हर दिन कुछ नया सीखते हैं ... – Lucas

1

अस्थायी/रावल्यू के लिए, आप केवल एक कॉन्स्ट संदर्भ कर सकते हैं।

आपके पास गैर-अस्थायी/lvalue के लिए एक गैर-कॉन्स्ट संदर्भ हो सकता है।

A a; 
A& b = a; 

मेरा मानना ​​है कि कारण है कि तथ्य यह है कि एक rvalue अस्थायी है के रूप में वहाँ कुछ है कि क्षण भर गायब करने जा रहा है को संशोधित करने में सक्षम होने में कम मूल्य है सुदृढ़ करने के लिए है।

+1

अनुमोदित; मुझे लगता है कि ओपी यह देख रहा है कि ऐसा क्यों है। – fbrereto

1

सी ++ भाषा में एक रावल्यू के लिए एक गैर-कॉन्स्ट संदर्भ संलग्न करना अवैध है, जबकि यह एक राल्लू के लिए एक संदर्भ संदर्भ संलग्न करने के लिए बिल्कुल ठीक है। उदाहरण के लिए, इस कानूनी

const int& r = 5; 

जबकि इस

int &r = 5; // ERROR 

प्रकार A अभिव्यक्ति A() द्वारा वापस की एक अस्थायी वस्तु एक rvalue है नहीं है, इसलिए ऊपर नियम के रूप में अच्छी तरह से अपने मामले में लागू होता है है।

+0

एक रैल्यू एक अज्ञात अस्थायी मान है, जैसे किसी फ़ंक्शन का रिटर्न वैल्यू। – thebretness

+0

@thebretness: जरूरी नहीं। उदाहरण के लिए, एक enum निरंतर एक रैल्यू है, फिर भी यह * नाम * है। – AnT

3

इस पर शब्दावली थोड़ा उलझन में है; आप उन्हें थोड़ी और आगे खोजना चाह सकते हैं। यहां संक्षिप्त जवाब दिया गया है:

आप एक अस्थायी वस्तु (कक्षा के कन्स्ट्रक्टर को कॉल करने का परिणाम) को एक चर में असाइन कर रहे हैं। एक अस्थायी वस्तु एक आर-मान है। आप गैर-कॉन्स्ट संदर्भ के लिए आर-मान असाइन नहीं कर सकते हैं।

आपको किसी कॉन्स्ट संदर्भ के लिए आर-वैल्यू असाइन करने की अनुमति है, हालांकि इसे अनुमति देने के लिए तर्क बहुत अस्पष्ट है।

0

मानक इसलिए कहते हैं क्योंकि:

§8.5.3.5 ... अन्यथा, संदर्भ एक गैर अस्थिर स्थिरांक प्रकार के लिए एक lvalue संदर्भ होगा ...

हालांकि, अगर आप यह बहुत ज्यादा चाहते हैं, तो आप इसे प्राप्त कर सकते हैं:

#include <iostream> 
int main() 
{ 
    const int & cr=5; 
    int & r=const_cast<int &>(cr); 
    r=6; 
    std::cout<<r; 
} 
// outputs 6 with c++/clang++, Debian 8, amd64 

लेकिन ध्यान रखें कि माना जाता निरंतर करोड़ किसी भी अधिक है, भी const नहीं है हो सकता है, और आप अपरिभाषित व्यवहार उठाना। (§1.9 (4))

उपर्युक्त कोड द्वारा सुझाए गए अनुसार, अंतर के लिए कोई तकनीकी कारण नहीं है। इसके बजाय, डिजाइनरों को दुःस्वप्न था कि उपयोगकर्ता अस्थायी संदर्भों के साथ गैर-कॉन्स्ट संदर्भों के साथ क्या करेंगे।