2016-09-27 12 views
13

सी ++ समिति ने क्यों फैसला किया कि कॉन्स संदर्भों को अस्थायी जीवनकाल का विस्तार करना चाहिए?क्यों कॉन्स संदर्भ रावल के जीवनकाल का विस्तार करते हैं?

इस तथ्य को पहले से ही व्यापक रूप से ऑनलाइन चर्चा की गई है, जिसमें स्टैक ओवरफ्लो भी शामिल है।

GotW #88: A Candidate For the “Most Important const”

इस भाषा सुविधा के लिए तर्क क्या था: निश्चित संसाधन समझा कि यह मामला है शायद इस GoTW है? क्या यह ज्ञात है?

(वैकल्पिक होगा कि temporaries के जीवनकाल कोई संदर्भ द्वारा लागू नहीं होता।)


औचित्य के लिए मेरा अपना पालतू सिद्धांत है कि इस व्यवहार वस्तुओं कार्यान्वयन विवरण को छिपाने के लिए अनुमति देता है। इस नियम के साथ, एक सदस्य फ़ंक्शन क्लाइंट कोड में किए गए किसी भी बदलाव के बिना पहले से ही आंतरिक रूप से मौजूद मूल्य के मान या कॉन्स्ट संदर्भ को वापस करने के बीच स्विच कर सकता है। उदाहरण के लिए, एक मैट्रिक्स क्लास पंक्ति वैक्टर और कॉलम वैक्टर वापस करने में सक्षम हो सकती है। प्रतियों को कम करने के लिए, या तो एक या दूसरे को कार्यान्वयन (पंक्ति प्रमुख बनाम कॉलम प्रमुख) के आधार पर संदर्भ के रूप में वापस किया जा सकता है। जो भी संदर्भ द्वारा वापस नहीं किया जा सकता है उसे प्रतिलिपि बनाकर वापस लौटाया जाना चाहिए और उस मूल्य को वापस कर देना चाहिए (यदि लौटा वैक्टर सम्मिलित हैं)। लाइब्रेरी लेखक भविष्य में कार्यान्वयन को बदलने के लिए छूट ले सकता है (पंक्ति प्रमुख बनाम कॉलम प्रमुख) और ग्राहकों को कोड लिखने से रोकता है जो दृढ़ता से निर्भर करता है कि कार्यान्वयन पंक्ति प्रमुख या स्तंभ प्रमुख है या नहीं। क्लाइंट को कॉन्स्ट रेफ के रूप में रिटर्न वैल्यू स्वीकार करने के लिए कहकर, मैट्रिक्स क्लास क्लाइंट कोड में किसी भी बदलाव के बिना या तो कॉन्स रेफ या वैल्यू लौटा सकता है। भले ही, मूल तर्क ज्ञात है, मैं इसे जानना चाहता हूं।

+0

मैट्रिक्स उदाहरण एक प्रॉक्सी वस्तु का उपयोग कर अधिक सुंदर ढंग से हल किया जा जाएगा। – 5gon12eder

+2

आपको निश्चित उत्तर के लिए "सी ++ के डिजाइन और विकास" की जांच करनी होगी। लेकिन मुझे दृढ़ता से संदेह है कि इस प्रश्न का एक उद्देश्य जवाब है - व्यक्तिगत पालतू सिद्धांतों से कोई फर्क नहीं पड़ता। – MSalters

+0

@ 5gon12eder मुझे लगता है कि आप जो सुझाव दे रहे हैं वह समाधान है जिसे मैं पूर्व-खाली करने की कोशिश कर रहा था, यह निर्धारित करके कि लौटा वेक्टर संगत होना चाहिए (किसी भी कारण से ...)। – Praxeolitic

उत्तर

14

यह 1 99 3 में प्रस्तावित किया गया था। इसका उद्देश्य संदर्भों के बावजूद अस्थायी हैंडलिंग को खत्म करना था।

फिर वापस, आरवीओ जैसी कोई चीज़ नहीं थी, इसलिए संदर्भ में एक अस्थायी बाध्यकारी पर प्रतिबंध लगाने पर एक प्रदर्शन हिट होता।

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1993/N0345.pdf

+1

वाह, मैं उस समय 10 वर्ष का था। वास्तव में कारणों को जानना दिलचस्प है। कागज के लिंक के लिए +1। – skypjack

+2

@skypjack 1993 वह वर्ष था जब मैंने पहली बार प्रोग्रामिंग छोड़ दी क्योंकि मुझे कुछ साहस चाहिए ... –

+0

आपका दूसरा पैराग्राफ मुझे स्पष्ट नहीं है। क्या आप ऐसे मामले का वर्णन कर सकते हैं जहां अस्थायी की प्रतिलिपि बनाने का प्रदर्शन जुर्माना (संभावित रूप से आरवीओ द्वारा टालने योग्य है, लेकिन जो माना जाता है) को अस्थायी बाध्यकारी द्वारा संदर्भित किया जा सकता है? निश्चित रूप से एक लटकन संदर्भ बनाने के बिना। –

2

आप सवाल नहीं कर रहे हैं क्यों अस्थायी संदर्भों को अस्थायी रूप से बांधने की अनुमति है, लेकिन केवल वे अस्थायी लोगों के जीवनकाल का विस्तार क्यों करते हैं।

struct A 
{ 
    void foo() const; 
}; 

A bar(); 

const A& a = bar(); 

a.foo();    // (1) 

अस्थायी bar() द्वारा लौटाए के जीवनकाल बढ़ाया नहीं कर रहे थे, तो a के किसी भी उपयोग (लाइन द्वारा उदाहरण (1)) नेतृत्व करेंगे अपरिभाषित व्यवहार करने के लिए:

इस कोड पर विचार करें। इससे अस्थायी गैर-पैरामीटर कॉन्स संदर्भ अस्थायी रूप से बेकार हो जाएंगे।


संपादित (संबोधित कर OP's comment):

इस प्रकार असली सवाल क्यों एक स्थिरांक संदर्भ चर (है कि एक समारोह पैरामीटर नहीं है) एक अस्थायी करने के लिए बाध्य करने के लिए अनुमति दी है होना चाहिए। मुझे इसके लिए मूल औचित्य नहीं पता है (Richard Hodges' answer एकमात्र सही हो सकता है), लेकिन यह हमें एक उपयोगी सुविधा प्रदान करता है। निम्न उदाहरण को ध्यान में रखते:

struct B 
{ 
    virtual void foo() const; 
}; 

B bar(); 

const B& b = bar(); 

b.foo();    // (1) 

पिछले एक से इस उदाहरण का फर्क सिर्फ इतना है कि B::foo() आभासी है। अब, अगर हम B के उप-वर्ग के रूप में एक नई कक्षा D पेश करने का निर्णय लेते हैं और bar()B से D पर वापसी प्रकार बदलते हैं?

struct B 
{ 
    virtual void foo() const; 
}; 

struct D : B 
{ 
    virtual void foo() const; 
}; 

//B bar(); 
D bar(); 

const B& b = bar(); 

b.foo(); // This will call D::foo() 

// In the end the temporary bound by b will be correctly destroyed 
// using the destructor of D. 

इस प्रकार, temporaries को स्थिरांक संदर्भ बाध्यकारी वस्तुओं है कि मूल्य द्वारा दिया जाता है के लिए गतिशील बहुरूपता का लाभ लेने के सरल करता है।

+0

सही उत्तर, क्या आप संदर्भ अभिव्यक्ति के रैवल्यू और लैवल्यू प्रकारों के बारे में कुछ जोड़ सकते हैं? – Trevir

+0

@Trevir क्षमा करें, लेकिन मुझे नहीं लगता कि यह उत्तर कैसे सुधार सकता है (ओपी के सवाल के संबंध में)। – Leon

+1

जब तक मैं उलझन में नहीं हूं, यह उत्तर थोड़ा अति-शाब्दिक लगता है। मुझे नहीं पता कि प्रश्न शब्द भ्रामक था या नहीं, लेकिन मुझे यह सुझाव देने का मतलब नहीं था कि यह किसी भी तरह से अस्थायी संदर्भों के लिए कॉन्स्ट संदर्भों के बारे में समझ सकता है लेकिन अपने जीवनकाल का विस्तार नहीं करता है। प्रश्न यह है कि क्यों सम्मेलन संदर्भ अस्थायी बाध्य कर सकते हैं * और * उनके जीवनकाल का विस्तार करना है। – Praxeolitic

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