2009-02-16 7 views
13

क्या मुझे नेस्टेड कोशिश-पकड़ ब्लॉक हो सकते हैं? उदाहरण के लिए:क्या मैं सी ++ में नेस्टेड कोशिश-पकड़ ब्लॉक कर सकता हूं?


void f() 
{ 
    try 
    { 
     //Some code 
     try 
     { 
      //Some code 
     } 
     catch(ExceptionA a) 
     { 
      //Some specific exception handling 
     } 
     //Some code 
    } 
    catch(...) 
    { 
     //Some exception handling 
    } 
}//f 
+3

आपको इन लोगों से प्यार करना होगा जो सोचते हैं कि वे सभी की तुलना में अधिक स्मार्ट हैं और सोचते हैं कि वे इस वेबसाइट के मालिक हैं –

+2

मैं आमतौर पर इन प्रकार के प्रश्नों को संदेह का लाभ देता हूं: सिर्फ इसलिए कि यह आपके कंपाइलर पर काम करता है इसका मतलब यह नहीं है कि यह हिस्सा है मानक के। इसका उलटा भी सच है। – rmeador

+2

@Shoosh इस सवाल ने इसे देखने से कम से कम 90 सेकंड बचाया! –

उत्तर

19

हाँ पूरी तरह से कानूनी।

यह सबसे अच्छा होगा हालांकि किसी अन्य विधि में भीतरी लोगों को स्थानांतरित करने के तो यह क्लीनर लग रहा है और अपने विधि (रों) कर रहे हैं छोटे

1

हाँ, आप कर सकते हैं।

7

जैसा कि पहले ही कहा गया है, यह संभव है, लेकिन आप को देखने के लिए 'गिरावट के माध्यम से इस में'checheme। यदि पहली कोशिश-पकड़-ब्लॉक में आपका अपवाद पकड़ा जाता है, तो यह बाहरी पकड़-ब्लॉक द्वारा पकड़ा नहीं जाएगा। हालांकि अगर यह आंतरिक कैच-ब्लॉक द्वारा पकड़ा नहीं जाता है, तो यह बाहरी पकड़-ब्लॉक में एक मिलान अपवाद-हैंडलर खोजने का प्रयास करेगा।

आप अपने आंतरिक अपवाद-हैंडलर में throw; का उपयोग करके अगले अपवाद-हैंडलर को अपवाद भी स्पष्ट रूप से बढ़ा सकते हैं।

उदाहरण के लिए इस कोड:

try 
{ 
    try 
    { 
     throw std::runtime_error("Test"); 
    } 
    catch (std::runtime_error& e) 
    { 
     std::cerr << "Inner Exception-Handler: " << e.what() << std::endl; 
     throw; 
    } 
} 
catch (std::exception& e) 
{ 
    std::cerr << "Outer Exception-Handler: " << e.what() << std::endl; 
}

में परिणाम होगा:

Inner Exception-Handler: Test 
Outer Exception-Handler: Test

इसका कारण यह है std::runtime_error is derived from std::exception काम करता है। आपको यह भी ध्यान रखना चाहिए कि इस तरह के एक छोटे उदाहरण में एक दूसरे के बाद पकड़-ब्लॉक लिखना भी संभव है, लेकिन यदि आप पहले पकड़-ब्लॉक के बाद अन्य कोड निष्पादित करना चाहते हैं तो आपको उन्हें घोंसला करना होगा।

1

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

+3

यह उपयोगी है अगर बाहरी पकड़ अपवादों का एक अलग सेट संभालता है – MSalters

5

हाँ, यह कानूनी है। ouster के अनुसार, इसका निपटारा करने का एक तरीका है आंतरिक प्रयास-पकड़ ब्लॉक को अपने स्वयं के कार्य में रखना और उस बाहरी कार्य को अपने बाहरी प्रयास-पकड़ ब्लॉक से कॉल करना।

इसे संभालने का एक और तरीका एकाधिक पकड़ ब्लॉक के साथ है।

void f() 
{ 
    try 
    { 
     //Some code that throws ExceptionA 
     //Some code that throws ExceptionB 
    } 
    catch(ExceptionA ea) 
    { 
     //Some exception handling 
    } 
    catch(ExceptionB eb) 
    { 
     //Some exception handling 
    } 
}//f 

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

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