2011-11-15 14 views
7

यह F~ आउटपुट लेकिन मैं ~Fसबसे महत्वपूर्ण आधार नहीं .. लेकिन यह क्या है?

#include <iostream> 

struct Foo { 
    int _x; 
    operator const int &() const {return _x;} 
    ~ Foo() {std :: cout << "~";} 
}; 

void foo (const int &) 
{ 
    std :: cout << "F"; 
} 

int main() 
{ 
    foo (Foo()); 
} 

उम्मीद कर रहा था मैं दिखाने के लिए कि सबसे महत्वपूर्ण-स्थिरांक के बजाय एक अपवाद एक नियम है प्रति एक के रूप में इस का निर्माण किया। यह सामान्य रूप से, के रूप में

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

मुझे लगता है कि वर्णन करने के लिए कोशिश कर रहा था के जीवनकाल के लिए बढ़ा दिया गया है लिखा है, हालांकि Foo() है एक अस्थायी, रूपांतरण ऑपरेटर द्वारा लौटा _x का संदर्भ नहीं है, और उपर्युक्त कोड असुरक्षित है।

लेकिन उत्पादन साबित होता है कि उदाहरण के सुरक्षित है लगता है, अस्थायी Foo() के जीवनकाल अपने सदस्यों में से एक के लिए एक स्थिरांक संदर्भ के अस्तित्व के लिए बढ़ा दी है।

क्या यह सही है? मानक में कहां निर्दिष्ट है?

+0

संदर्भ रिटर्निंग अधिक बार एक अच्छा एक से एक बुरा विचार है। यह इस तरह का एक अच्छा उदाहरण है। –

+0

@ आर। मार्टिनिन्हो फर्नांडीस तो आप 'ऑपरेटर []' के रूप में घोषित करते हैं ...? – curiousguy

उत्तर

6

अस्थायी लोगों के संबंध में सामान्य नियम यह है कि पूर्ण जीवन अभिव्यक्ति समाप्त होने पर उनका जीवन समाप्त होता है (अनौपचारिक रूप से, ; तक पहुंचने पर)।

12,2 अस्थायी वस्तुओं

3/ [...] अस्थायी वस्तुओं पूर्ण अभिव्यक्ति (1.9) कि (lexically) का मूल्यांकन करने में अंतिम चरण के रूप में नष्ट कर रहे हैं, जहां वे शामिल बनाये गये। यह सच है भले ही वह मूल्यांकन अपवाद फेंकने में समाप्त हो। अस्थायी वस्तु को नष्ट करने के मूल्य गणना और दुष्प्रभाव केवल पूर्ण अभिव्यक्ति के साथ जुड़े होते हैं, न कि किसी विशिष्ट उप-संपीड़न के साथ।

1

ऐसा इसलिए है क्योंकि अस्थायी कार्य कॉल की पूरी अवधि के लिए अस्थायी रहता है। जब आप foo (Foo()); कर यहाँ क्या होता है:

  1. अस्थायी Foo रचना की जाती है, तो
  2. operator const int& अस्थायी
  3. foo() पर कहा जाता है कहा जाता है और इस F
  4. आउटपुट एक बार foo() रिटर्न अस्थायी Foo नष्ट हो जाता है और यह आउटपुट ~
+0

विस्तारित करने के लिए: कोड तब तक सुरक्षित है जब तक 'foo' संदर्भ को संग्रहीत नहीं करता है। –

1

यहां कोई जादू नहीं है। सभी फ़ंक्शन तर्क कॉलर के दायरे में रहते हैं, जिसमें अस्थायी भी शामिल हैं। अस्थायी Foo() कॉलर के दायरे में बनाया गया है, और लाइन के अंत में नष्ट हो गया है।

तो समारोह foo() करता होता है जो कुछ से पहले main() में अपने तर्क नष्ट कर रहे हैं।

0

लेकिन आपका Foo उदाहरण यहां हमेशा से रहने वाला था जब तक कि यह अर्धविराम उस वक्तव्य को समाप्त नहीं कर देता था जिसमें इसे बनाया गया था। किसी फ़ंक्शन कॉल में किसी सदस्य को संदर्भित करने से उसे कोई बदलाव नहीं आया।

प्रयास करें:

int const &ref = Foo(); 
foo(ref); 

बनाम

Foo const &ref = Foo(); // or function returning temp 
foo(ref);