2014-04-06 4 views
5

एक संदर्भ मैं निम्नलिखित कोड दुखी विफल उम्मीद करेंगे पकड़े एक वर्ग बीत रहा है, लेकिन यह संकलित:क्लास एक संदर्भ प्रतिलिपि रखने वाला वर्ग क्यों है?

#include <iostream> 

struct ReferenceHolder 
{ 
    std::string& str; 

    ReferenceHolder(std::string& str) 
    : str(str) 
    {} 
}; 

// Why does this compile? 
ReferenceHolder f() { 
    std::string str = "Hello"; 
    return ReferenceHolder(str); 
} 

int main() { 
    ReferenceHolder h = f(); 
    std::cout << "Should be garbage: " << h.str << '\n'; 
    return 0; 
} 

संकलक: जी ++ 4.7.2 (-std साथ = C++ 11)

संपादित करें: यहां तक ​​कि -फनो-एलिइड-कन्स्ट्रक्टर के साथ यह खुशी से संकलित करता है

+0

स्पष्ट रूप से इसे स्थानांतरित किया जा रहा है। यदि आप स्पष्ट रूप से चालक कन्स्ट्रक्टर को हटाते हैं तो यह संकलित नहीं होता है। – jrok

+0

@jrok True, लेकिन जहां तक ​​मैं देख सकता हूं कि यह कॉपी करने योग्य और जंगम दोनों है। – dyp

+0

दिलचस्प बात यह है कि मिल सीपीयू (सुरक्षा वार्ता) की प्रस्तुति के अनुसार, इस वास्तुकला पर आपको एक सेगमेंटेशन गलती मिल जाएगी। –

उत्तर

7

आपकी कक्षा की प्रतिलिपि बनाने में कोई समस्या नहीं है, जैसा कि आपका उदाहरण करता है: नया संदर्भ बस उसी वस्तु को पुराने के रूप में संदर्भित करने के लिए शुरू किया गया है। बेशक, जब आप फ़ंक्शन वापस संदर्भ लटकते हैं तो आपको अपरिभाषित व्यवहार मिलता है।

संदर्भ डिफ़ॉल्ट-प्रारंभिकरण और प्रति-कार्य रोकता है; इसलिए निम्नलिखित कारणों से निम्नलिखित छोटे बदलाव विफल हो जाएंगे:

ReferenceHolder h; // ERROR: can't default-initialise the reference 
h = f();   // ERROR: can't reassign the reference. 
1

इस कोड में अपरिभाषित व्यवहार है, the classic answer from Eric Lippert देखें।

h में संदर्भ f() से वापसी मान में संदर्भ है, जो बदले अभिव्यक्ति में ReferenceHolder के लिए बाध्य है के लिए बाध्य है, और इसलिए h संदर्भ str इसके दायरे से बाहर f() से।

+0

मुझे पता है कि। देखें: "कचरा होना चाहिए" –

+1

@ डाइटर लुकिंग: अपरिभाषित व्यवहार का मतलब "कचरा" नहीं है, इसका मतलब है "कुछ भी"। – Mankarse

+1

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

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