2012-05-17 15 views
10

मुझे आश्चर्य है कि इस लाइन एक dangling सूचक बनाता है, तो:std :: runtime_error कन्स्ट्रक्टर में पारित स्ट्रिंग की प्रतिलिपि बनाता है?

string arg="derp"; 
throw std::runtime_error("Unknown argument "+arg); 

std::runtime_error कॉपी करता है string, या यह संदर्भ की दुकान करता है?

+0

आपका शीर्षक 'std :: अपवाद' कहता है लेकिन कोड 'std :: runtime_error' है। ध्यान दें कि 'std :: runtime_error' अपवाद वर्ग है जो एक संदेश लेता है, जैसा कि आप कर रहे हैं, लेकिन' std :: अपवाद 'नहीं है, इसलिए शीर्षक बहुत अधिक समझ नहीं लेता है (यानी, 'std :: अपवाद '* एक स्ट्रिंग-स्वीकार्य कन्स्ट्रक्टर नहीं है *। – GManNickG

+0

@GManNickG को सही किया गया। –

उत्तर

9

std::exception (जो std::runtime_error विरासत से प्राप्त) को संदेश की प्रतिलिपि बनाना चाहिए, भले ही इसे मानक में स्पष्ट रूप से नहीं कहा जाता है (जो मुझे मिल सकता है)। exception कक्षा के लिए what() संदेश का स्रोत सामान्य स्थिति में इसे समाप्त करने का कोई कारण नहीं है।

+0

+1; स्थानीय स्कोप में सभी ऑब्जेक्ट्स को नष्ट कर दिया जाएगा जब अपवाद फेंक दिया जाता है, इसलिए मूल रूप से कुछ भी नहीं पहुंच सकता है, लेकिन स्ट्रिंग अक्षर यदि कोई प्रतिलिपि नहीं बना लेता है। –

+0

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

+0

@ माइकलबुर: हालांकि, वास्तव में कहां कहा गया है? (जाहिर है कि पैडेंट भूमि में अब, लेकिन मैं उत्सुक हूं।) जो कुछ कहा गया है वह है कि 'std :: runtime_error' के निर्माण के बाद' what_arg' नामक 'std :: stringc ',' std :: strcmp (क्या (), what_arg.c_str()) == 0'। यह कहा अपवाद वस्तु की प्रतियों के बारे में कुछ भी नहीं कहता है। – GManNickG

0

पॉइंटर कहां है? रनटाइम त्रुटि बनाते समय आप एक स्ट्रिंग अक्षरशः प्रतिलिपि बना रहे हैं और इसे const std::string& पर निहित रूप से कास्टिंग कर रहे हैं।

+0

बिंदु यह है: क्या runtime_error उस अस्थायी वस्तु को संदर्भित करता है (इसे पॉइंटर कहने के लिए खेद है), या क्या यह इसकी प्रतिलिपि बनाता है (जो मुझे आशा है)? –

+0

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

+0

@ AJG85: मैंने अपनी टिप्पणी हटा दी क्योंकि यह गलत था। – GManNickG

0

यह एक स्ट्रिंग रिफ्रेंस लेता है। और संदर्भ के रूप में पकड़ ब्लॉक को पास करता है, हालांकि यदि आप कन्स्ट्रक्टर में एक स्ट्रिंग को कर्कश पास करते हैं तो यह एक अस्थायी स्ट्रिंग ऑब्जेक्ट बनाएगा। साथ ही, एक स्ट्रिंग कड़वाहट के साथ + arg मत करो, यह एक वाक्यविन्यास त्रुटि है।

+2

यह नहीं है। एक ऑपरेटर + अधिभार है जो इसे अनुमति देता है। –

+1

@LorenzoPistone कोई ऑपरेटर + प्रकार कॉन्स char * पर नहीं है। – johnathon

+0

http://ideone.com/bIJw2 –

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