2010-11-10 15 views
8

मैं मान लिया जाये कि है:सी ++ स्थिरांक lvalue संदर्भ

  • वर्ग एक जो गैर copyable है
  • वर्ग बी जो एक सदस्य के रूप में स्थिरांक एक & है एक (और इसके constructer में एक एक लेता है और यह सेट इसके प्रारंभ सूची)
  • एक समारोह में A GenerateA();

इसका मतलब यह है कि यह करने के लिए वैध होना चाहिए: बी (GenerateA()) ?

यानी, क्या कॉन्स्ट रेफ का मतलब है कि ए उत्पन्नकर्ता ए() रिटर्न का कोई प्रति नहीं किया जाता है? और क्या इसका मतलब यह है कि लौटा अस्थायी का दायरा तब तक बढ़ाया जाता है जब तक बी मौजूद है?

संपादित करें: टिप्पणियों से युद्ध प्रश्न: यह एक स्थानीय एक को GenerateA() से एक एक & वापस जाने के लिए स्वीकार्य है, अगर lvalue एक स्थिरांक एक & है?

धन्यवाद!

+0

आप जीवन के समाप्त होने वाले मूल्य के संदर्भ में नहीं रह सकते हैं; जो वास्तव में होता है जब आप किसी स्थानीय चर के संदर्भ को वापस करते हैं। – GManNickG

+0

@GMan: यह अनिवार्य रूप से मेरे प्रश्न का इरादा था, यानी, एक कॉन्स्ट संदर्भ का उपयोग करते हुए कहा गया वस्तु का जीवनकाल बदलता है। –

उत्तर

3

के रूप में यह पहले से ही दूसरों के द्वारा कहा गया है, A GenerateA() अगर A copyable नहीं है संकलन नहीं कर सकते।

स्थिरांक रेफरी के बारे में: नहीं, अस्थायी के जीवनकाल बी के जीवनकाल मानक [12.2.5] के लिए बढ़ा दिया नहीं किया जाएगा राज्यों:

एक में एक संदर्भ सदस्य के लिए एक अस्थायी बाध्य कन्स्ट्रक्टर का सीटीओ-प्रारंभकर्ता (12.6.2) तब तक बना रहता है जब तक कि निर्माता बाहर निकलता है। [...] फ़ंक्शन रिटर्न स्टेटमेंट (6.6.3) में लौटाए गए मान के लिए अस्थायी बाध्य कार्य पूरा होने तक जारी रहता है।

तो हाँ, एक अस्थायी के जीवनकाल का विस्तार कुछ संदर्भों में मौजूद है (और कुछ समय वास्तव में उपयोगी है: see this article), लेकिन एक आप प्रस्तुत में नहीं।

अपने अंतिम प्रश्न के संबंध में, GenerateA() से स्थानीय चर के संदर्भ को वापस करने के लिए कानूनी नहीं है (और परिणाम को बाध्यकारी संदर्भ में किसी भी मदद से नहीं होगा)।

+0

+1, इस विशेष भत्ता के बारे में पता नहीं था। – casablanca

0

हाँ और नहीं।

हाँ, स्थिरांक संदर्भ अस्थायी चर के लिए बाध्य होगा। नहीं, कॉन्स संदर्भ जो वर्ग के सदस्य हैं, वे स्वचालित अवधि के साथ जीवनकाल का विस्तार नहीं करते हैं।

+0

क्या आप मुझे मानक में प्रासंगिक खंड में इंगित कर सकते हैं? और, यह * काम नहीं करता है। कंपाइलर (चाहिए, जीसीसी करता है) वस्तु ए के लिए बनाई गई प्रतिलिपि के बारे में शिकायत करें। –

+2

@ जॉन: यही कारण है कि 'ए' को 'जेनरेशन()' से कॉपी द्वारा वापस किया जा रहा है, न कि शेष कोड द्वारा। मानक को 'जेनरेटा() 'कॉल करने के लिए एक सुलभ प्रति कन्स्ट्रक्टर (या, अंत में, एक चालक कन्स्ट्रक्टर) की आवश्यकता होती है। –

+0

@Andre: धन्यवाद! –

4

यदि A गैर-प्रतिलिपि योग्य है, तो फ़ंक्शन A GenerateA() अमान्य है क्योंकि मान द्वारा लौटने से एक प्रतिलिपि बनाने की आवश्यकता होती है।

यदि फ़ंक्शन इसके बजाय संदर्भ देता है (यानी A &GenerateA()) और संदर्भ स्थानीय रूप से बनाए गए A ऑब्जेक्ट के लिए है, तो जैसे ही फ़ंक्शन निकलता है, यह अमान्य हो जाता है। सी ++ में कचरा संग्रह का कोई भी रूप नहीं है, इसलिए जब तक उपयोग में है तब तक ऑब्जेक्ट के जीवनकाल को "विस्तारित" करने का कोई तरीका नहीं है।

+0

क्या आप उस पर विस्तार कर सकते हैं? क्या प्रतिलिपि की आवश्यकता है क्योंकि इसे ऑब्जेक्ट को दाएं स्टैकफ्रेम पर प्राप्त करना है? क्या ए और जेनरेटा() से स्थानीय ए में लौटने के लिए स्वीकार्य है, यदि लाल्व एक कॉन्स ए है? धन्यवाद! –

+2

@ जॉन बाइंड: ढेर फ्रेम कार्यान्वयन-निर्भर हैं और यह प्रभावित नहीं करते कि भाषा कैसे काम करती है। मूल्य द्वारा लौटने की शब्दावली यह है कि एक प्रतिलिपि बनाई गई है - भले ही संकलक इसे अनुकूलित कर सके, फिर भी ऑब्जेक्ट की प्रतिलिपि नहीं बनाई जा सकती है, यह अभी भी एक त्रुटि है। – casablanca

+0

@ कैसाब्लांका: जानना अच्छा है। धन्यवाद। साइड पॉइंट: "कंपाइलर अनुकूलित कर सकता है" == आरवीओ? –

0

यहाँ एक उदाहरण है:

#include <iostream> 
using namespace std; 

int& GenX(bool reset) 
{ 
    static int* x = new int; 
    *x = 100; 
    if (reset) 
    { 
     delete x; 
     x = new int; 
     *x = 200; 
    } 
    return *x; 
} 

class YStore 
{ 
public: 
    YStore(int& x); 
    int& getX() { return my_x; } 
private: 
    int& my_x; 
}; 

YStore::YStore(int& x) 
: my_x(x) 
{ 
} 

int main() 
{ 
    YStore Y(GenX(false)); 
    cout << "X: " << Y.getX() << endl; 
    GenX(true); // side-effect in Y 
    cout << "X: " << Y.getX() << endl; 
    return 0; 
} 

आउटपुट:

X: 100 
X: 200 
+1

यह एक संदर्भ का उपयोग करने के उद्देश्य को हरा देता है, और एक स्मृति रिसाव बनाता है। – casablanca

+1

यह खराब कोड है। – GManNickG

+0

यह भाषा का दुरुपयोग करता है, हां। –

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