2010-01-18 9 views
10

निम्न कोड C++ में कैसे काम करता है? क्या यह तार्किक है?कॉन्स संदर्भों के लिए प्रारंभिक प्रारंभ

const int &ref = 9; 
const int &another_ref = ref + 6; 

सी ++ गैर-कॉन्स्ट संदर्भों के लिए अनुमति नहीं होने पर कॉन्स्ट संदर्भों के लिए शाब्दिक प्रारंभिक अनुमति क्यों देता है? उदा .:

const int days_of_week = 7; 
int &dof = days_of_week; //error: non const reference to a const object 

इस तथ्य यह है कि, एक गैर स्थिरांक संदर्भ चर यह करने के लिए बात कर रहा है के मूल्य को बदलने के लिए इस्तेमाल किया जा सकता से समझाया जा सकता। इसलिए, सी ++ एक कॉन्स वैरिएबल के गैर-कॉन्स्ट संदर्भ की अनुमति नहीं देता है।

क्या यह एक संभावित स्पष्टीकरण हो सकता है? सी ++ अनुमति नहीं देता:

int &ref = 7; 

क्योंकि वह तार्किक नहीं है, लेकिन:

const int val = 7; 

तो शाब्दिक प्रारंभ स्थिरांक चर के लिए अनुमति दी है:

const int &ref = 7; 

के लगभग बराबर है।

पीएस .: मैं वर्तमान में लिप्पमैन के सी ++ प्राइमर का अध्ययन कर रहा हूं।

उत्तर

7

तो तुम इस तरह कोड लिख सकते हैं:

void f(const string & s) { 
} 

f("foobar"); 

हालांकि सख्ती से बोला क्या वास्तव में यहाँ क्या हो रहा है शाब्दिक एक स्थिरांक संदर्भ के लिए बाध्य नहीं किया जा रहा है - के बजाय एक temprary स्ट्रिंग वस्तु बनाई गई है:

string("foobar"); 

और यह नामहीन स्ट्रिंग संदर्भ के लिए बाध्य है।

ध्यान दें कि गैर-पैरामीटर संदर्भ चर बनाने के लिए वास्तव में असामान्य है - संदर्भों का मुख्य उद्देश्य फ़ंक्शन पैरामीटर और वापसी मूल्यों के रूप में कार्य करना है।

6

लगातार संदर्भ शाब्दिक और temporaries साथ प्रारंभ किया जा सकता है क्योंकि आप तुच्छता से स्पष्ट चर करने के लिए उन्हें बदल सकता है:

int const& ans = 42; 
// tranformed: 
int __internal_unique_name = 42; 
int const& ans = __internal_unique_name; 

या जब जीवनकाल बढ़ाया नहीं है, इस तरह के एक समारोह पैरामीटर के रूप में:

f("foobar"); 
// transformed: 
{ 
    string __internal_unique_name = "foobar"; 
    f(__internal_unique_name); 
} 

(इस मामले में स्पष्ट ब्लॉक पर ध्यान दें।)

हालांकि गैर-निरंतर मामले में ऐसा कुछ करना संभव है, यह सिर्फ इतना नहीं है धारा C++ में अनुमति दी। सी ++ 0x (अगला मानक), हालांकि, आर-वैल्यू संदर्भ होंगे।


यदि यह स्पष्ट नहीं था, ref + 6 अपने कोड से एक अस्थायी वस्तु है, जो आप के रूप में कल्पना कर सकते हैं बनाता है:

int const& ref = int(9); 
int const& another_ref = int(ref + 6); 

// transformed: 
int __A = 9; 
int const& ref = __A; 
int __B = ref + 6; 
int const& another_ref = __B; 

यह मदद मिल सकती है कि आप समझते हैं/कल्पना क्या हो रहा है, लेकिन आप चाहिए इस तरह असली कोड नहीं लिखो।इसके अलावा मैंने उन नामों को कार्यान्वित करने के लिए डबल अंडरस्कोर नामों का उपयोग किया है (कंपाइलर द्वारा उपयोग किया जाता है) और आपके द्वारा उपयोग नहीं किया जाना चाहिए। कोई भी नाम जिसमें आसन्न अंडरस्कोर शामिल है, सी ++ कार्यान्वयन के लिए आरक्षित है।

+0

+1। लेकिन मुझे लगता है कि आपका दूसरा उदाहरण { स्ट्रिंग __internal_unique_name ("foobar") में बदल दिया जाएगा; एफ (__ internal_unique_name); } – mmmmmmmm

+0

@ रिस्टवेन्स: इससे कोई फर्क नहीं पड़ता: रूपांतरण स्पष्ट नहीं होना चाहिए, इस मामले में वे वही हैं। –

2

आपका कोड सी ++ मानक नियम तक उबाल जाता है जहां अस्थायी मूल्य का जीवनकाल const संदर्भ के जीवनकाल तक सीमित होता है जिसके संदर्भ में इसे असाइन किया जाता है। अतिरिक्त विवरण के लिए GoTW आलेख GotW #88: A Candidate For the “Most Important const” देखें।

उदाहरण के लिए, ScopeGuard कार्यान्वयन, डॉ। डॉब्स लेख "Generic: Change the Way You Write Exception-Safe Code — Forever" में अलेक्जेंड्रेसकु और मार्जिनन द्वारा वर्णित कार्यान्वयन इस व्यवहार पर निर्भर करता है।