2012-01-23 17 views
10

में कैच ब्लॉक के अंदर कुछ फेंकने का प्रयास करता हूं तो यह समाप्ति क्यों करता है मेरे पास निम्न C++ कोड है और यह मुझे आश्चर्यचकित करता है। समस्या यह है कि अगर मैं पकड़ ब्लॉक के अंदर फिर से फेंकने के अलावा कुछ फेंक देता हूं, प्रोग्राम को निरस्त करके कॉल किया जाएगा और जीसीसी 4, में त्रुटि संदेश दिया जाएगा "टर्म 'को' int 'के उदाहरण को फेंकने के बाद बुलाया जाता है। अगर मैं सिर्फ "फेंक" का उपयोग करता हूं पकड़ ब्लॉक के अंदर फिर से फेंकने के लिए, सब ठीक हो जाएगा।अगर मैं सी ++

#include <iostream> 
#include <exception> 
#include <stdexcept> 

using namespace std; 

int main() 
{ 
    try{ 
     throw std::string("first throw"); 
    } 
    catch(std::string &x){ 
     try{ 
      std::cout << x << std::endl; 
//   throw; // if I use this line, all is fine. 
      throw int(2); // but if I use this line, it causes Abort() to be called 
     } 
     catch (int &k){ 
      throw; 
     } 
     catch(...) 
     { 
      cout << "all handled here!"<< endl; 
     } 
    } 
    catch(...){ 
     std::cout<< "never printed" << endl; 
    } 
} 
+0

यदि आप किसी पकड़ से फेंकते हैं तो इसकी अपेक्षा की जा सकती है। – AJG85

उत्तर

7

आप throw इस प्रकार यह abort की ओर जाता है बुलाया जा रहा है किसी भी try हैंडलर के अंदर नहीं है।

यहाँ खरोज के साथ अपने कोड थोड़ा और कुछ टिप्पणियाँ इनलाइन साफ ​​है:

#include <iostream> 
#include <exception> 
#include <stdexcept> 

using namespace std; 

int main() 
{ 
    try { 
     throw std::string("first throw"); 
    } 
    catch (std::string &x) { 
     try { 
      std::cout << x << std::endl; 
      // throw; // if I use this line, all is fine. 
      throw int(2); // but if I use this line, it causes Abort() to be called 
     } 
     catch (int &k) { 
      // Catches and rethrows exception. Not inside a try thus leads to abort. 
      throw; 
     } 
     catch (...) { 
      // Will handle the case where the string is rethrown instead. No abort. 
      cout << "all handled here!"<< endl; 
     } 
    } 
    catch (...) { 
     std::cout<< "never printed" << endl; 
    } 
} 
+0

धन्यवाद, मार्टिन। आपकी टिप्पणियां इसे पाठकों के लिए स्पष्ट बनाती हैं! –

13

आप एक int फेंक, तो यह संभाला नहीं किया जाएगा; यह आंतरिक catch (int &k) हैंडलर द्वारा पकड़ा जाएगा, जो इसे पुनर्स्थापित करता है; और पुनर्स्थापना अपवाद को पकड़ने के लिए कोई बाहरी हैंडलर नहीं है, क्योंकि आप पहले से ही बाहरी catch ब्लॉक में हैं। तो इस मामले में, terminate को एक अनचाहे अपवाद के कारण बुलाया जाता है।

यदि आप string को पुनर्स्थापित करते हैं, तो यह आंतरिक catch(...) हैंडलर द्वारा पकड़ा जाता है; यह पुनर्स्थापना नहीं करता है, इसलिए अपवाद को संभाला गया है।

+0

धन्यवाद, माइक। मुझे लगता है कि आपका जवाब संक्षिप्त और बिंदु के लिए सही है। –

+0

स्ट्रिंग फेंकने के लिए यह सामान्य/अनुशंसित अभ्यास है? –

+0

@StephaneRolland: आमतौर पर, नहीं; रिपोर्टिंग त्रुटियों या अन्य स्थितियों के लिए जिन्हें स्थानीय रूप से संभाला नहीं जा सकता है, एक कस्टम प्रकार फेंक दें, आमतौर पर 'std :: अपवाद' का उप-वर्ग; और अन्य प्रयोजनों के लिए आप शायद पहले स्थान पर अपवादों का उपयोग नहीं करना चाहते हैं। लेकिन सीखने के लिए कि अपवाद कैसे काम करते हैं, 'स्ट्रिंग' और 'int' कुछ भी उतना ही अच्छा है। –