2012-09-22 35 views
13

आज rethrowing मैं एक catch ब्लॉक में एक बग मिला:अपवाद प्रकार खोने जब एक कैच ब्लॉक से एक अपवाद

catch (const exception& e){ 
    // do something 
    // throw e; <-- bug! 
    throw; // <-- right thing to do 
} 

मूल रूप से अगर मैं अपवाद eस्पष्ट rethrow, मैं एक नया std::exception का पुनर्निर्माण, में मिलता है वास्तव में what() विधि से संदेश मेरे कस्टम निर्मित संदेश के बजाय डिफ़ॉल्ट std::string था।

स्पष्टीकरण क्या है? मैंने सोचा कि throw; केवल throw ExceptionJustCaught; का एक शॉर्टेंड है।

+0

यह मूल्य और संदर्भ के बीच का अंतर है। –

+0

यह एक बहुत ही महत्वपूर्ण अवधारणा है जिसे अक्सर अनदेखा किया जाता है (और मेरी राय में सिंटैक्स का एक मुश्किल बिट है जिसे संकलित करते समय कम से कम चेतावनी दी जानी चाहिए ..)। महान सवाल! – NHDaly

उत्तर

13

अपवाद वस्तुएं थोड़ी विशेष हैं। वे स्मृति में एक विशेष स्थान पर बने हैं, और उनका जीवनकाल कैच ब्लॉक द्वारा निर्धारित किया जाता है जिसमें वे पकड़े जाते हैं।

अगर आप कहते हैं throw e;, मूल अपवाद के जीवनकाल कैच ब्लॉक के अंत में समाप्त हो जाती है, और आप e को कॉपी, इस प्रकार एक शास्त्रीय टुकड़ा करने की क्रिया समस्या का निर्माण करके कोई नया अपवाद फेंक रहे हैं: चूंकि e एक बहुरूपी संदर्भ है किसी ऑब्जेक्ट के लिए जिसका डायनामिकल प्रकार आमतौर पर std::exception से अधिक व्युत्पन्न होता है, तो आप ऑब्जेक्ट के व्युत्पन्न हिस्से को टुकड़ा कर देते हैं।

इसके विपरीत, throw; एक विशेष बयान है कि मूल अपवाद reactivates, इतना है कि यह नहीं रह गया है पकड़ा है, और अपने जीवन अब और ब्लॉक के अंत में नहीं अंत करता है। वास्तव में, यदि आप गैर-निरंतर संदर्भ से पकड़ते हैं, तो आप अपवाद ऑब्जेक्ट को संशोधित कर सकते हैं और फिर से स्थानांतरित कर सकते हैं और इस प्रकार राज्य को कम पकड़ ब्लॉक को बदल सकते हैं। लेकिन ध्यान रखें कि पुनर्विचार एक नया अपवाद फेंकने से अलग है!

8

बस एक throw संदर्भ द्वारा वर्तमान अपवाद फेंकता है। throw e प्रतिलिपि फेंकने के लिए एक नया अपवाद बनाता है। यह return काम करता है।

+0

"संदर्भ द्वारा"। वास्तव में, यह 'संदेश() 'का सही कार्यान्वयन नहीं खोना चाहिए, जो मेरा संदेश भालू है। –

+0

क्या आप एक पूर्ण, संकलित कोड उदाहरण पोस्ट कर सकते हैं, जितनी संभव हो उतनी लाइनें जो समस्या का प्रदर्शन करती हैं? सबसे अधिक संभावना है कि, आपकी प्रतिलिपि निर्माता संदेश को संरक्षित नहीं करता है। –

+0

केरेक के जवाब सही दिखते हैं, मुझे संदेह था कि एक टुकड़ा करने की समस्या है, इसलिए मैं इस सवाल को संपादित नहीं करूँगा क्योंकि मुझे लगता है कि इसका सही उत्तर दिया गया है। शायद डेविड सिर्फ अलग शब्दों के साथ सही है, लेकिन ईमानदारी से यह पर्याप्त स्पष्ट नहीं है। –

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