2012-04-21 16 views
5

मैं अपवाद हैंडलिंग जो इस प्रकार है लेखन डेस्कटॉप अनुप्रयोग परियोजना के लिए क्यूटी 4.8 (C++) का उपयोग कर रहा है, और:कैच ब्लॉक में दोहराए गए कोड लिखने से कैसे बचें?

void callerMethod() 
{ 
    try 
    { 
    method1(); 
    } 
    catch(Exception1& e) 
    { 
    // display critcal error message 
    // abort application 
    } 
    catch(std::Exception& e) 
    { 
    // print exception error message 
    } 
    catch(...) 
    { 
    // print unknown exception message 
    } 
} 

void method1() 
{ 
    try 
    { 
    // some initializations 
    // some operations (here exceptions can occur) 
    // clean-up code (for successful operation i.e no exception occurred) 
    } 
    catch(Exception1& e) 
    { 
    // clean-up code 
    throw e; 
    } 
    catch(Exception2& e) 
    { 
    // clean-up code 
    throw e; 
    } 
    catch(Exception3& e) 
    { 
    // clean-up code 
    throw e; 
    } 
    catch(...) 
    { 
    // clean-up code 
    throw; 
    } 
} 

तो मेरे सवाल का मैं हर कैच ब्लॉक में सफाई कोड लिखने की आवश्यकता क्यों है ? क्या कोई तरीका है कि मैं दोहराया कोड लिखने से बच सकता हूं?

नोट :: [Method1 में()] मैं फिर से फेंक के लिए अपवाद है जो करने के लिए हुआ मेरी caller.So मैं, एकल कैच ब्लॉक में उन्हें नहीं पकड़ सकते क्योंकि तब टाइप जानकारी चली जाएगी चाहते हैं ।

+4

टी का प्रयास करें o स्मार्ट पॉइंटर्स, कंटेनर क्लासेस इत्यादि का उपयोग करके आवश्यक क्लीन-अप कोड की मात्रा को कम करें आदर्श रूप से कोई क्लीन-अप कोड नहीं होना चाहिए। – user763305

+0

ऐसा प्रतीत होता है कि आप जो करना चाहते हैं वह बस {/ * फेंक सकता है * /} पकड़ सकता है (विशिष्ट_एक्सप्शन कॉन्स और ई) {/ * समाप्त * /} '। यदि आपको अपवाद प्रकार 'अपवाद 1',' अपवाद 2 'और अन्य पर ध्यान नहीं दिया जाता है, तो * उन्हें * पकड़ें नहीं। –

+1

इसके अलावा, भले ही आप संदर्भ से पकड़ लें, आपको * फेंकने से रोकने के लिए 'फेंकने 'के बजाय' फेंक' का उपयोग करके पुनर्स्थापित करना चाहिए। – ereOn

उत्तर

8

Method1 ज्यादा दो अवधारणाओं से सरल किया जा सकता:

  1. RAIIकिसी भी विनाशकों में क्लीन-अप कोड डालें, और क्लीन-अप कोड को केंद्रीकृत किया जाएगा।
  2. अयोग्य throw का उपयोग करें, और आपको अपवाद के प्रकार के बारे में जानने की आवश्यकता नहीं होगी।

तो, method1() दिखना चाहिए:

void method1() 
{ 
    // some initializations of RAII objects 
    // some operations (here exceptions can occur) 
} 

अगर आप std::exception से Exception1 निकाले जाते हैं, के बाद से what() विधि आभासी है callerMethod में पहली catch खंड हटाया जा सकता है।

+1

+1। मैं यह कहना चाहता था। आरएआईआई यहां समाधान है। – Nawaz

+0

लेकिन मैं कॉलर मोड() में अलग से अपवाद 1 को संभालना चाहता हूं। यदि अपवाद 1 हुआ तो मैं एप्लिकेशन को निरस्त करना चाहता हूं। – EngineeredBrain

+0

@ अनवरशेख: आप अभी भी ऐसा कर सकते हैं। आरएआईआई केवल आपकी सफाई समस्या हल करती है। – Nawaz

0

सभी अपने स्वच्छ ऊपर कोड पूरी तरह से समान है, तो आप अपनी पकड़ में सब कुछ कर सकते हैं (...) ब्लॉक:

try { 
    // code 
} catch (...) { 
    // cleanup 
    throw; 
} 

अपने कोड थोड़ा भिन्न होता है, तो आप हमेशा एक सफाई समारोह कॉल कर सकते हैं:

try { 
    // code 
} catch (exc1 ex) { 
    cleanup(args); 
    // exc1 specific 
    throw; 
} catch (exc2 ex) { 
    cleanup(args); 
    // exc2 specific 
    throw; 
} catch (...) { 
    cleanup(args); 
    throw; 
} 
+0

यदि मैं एकल पकड़ (..) लिखता हूं जो अपवाद फेंकता है, तो कॉलर विधि में मुझे कैसे पता चलेगा कि कौन सा अपवाद हुआ था। क्योंकि मैं अपवाद 1 को संभालना चाहता हूं जो एप्लिकेशन को रोकता है। – EngineeredBrain

1

आपको जितना संभव हो उतना अपवाद फेंकना चाहिए और कॉल श्रृंखला में जितना संभव हो उतना उच्च पकड़ना चाहिए। यह स्वचालित रूप से कम कोड डुप्लिकेशन का कारण बनता है, और त्रुटि प्रबंधन को केंद्रीकृत करता है। आप एक ही स्थान पर सभी को फेंक रहे/पकड़ रहे हैं, जो थोड़ा सा लगता है ... मजबूर।

मैं अक्सर बात (विशेष रूप से कार्यक्रम खत्म होने वाली अपवाद के लिए इस तरह का कार्य करें:।

int main() 
try 
{ 
    function_calls_that_may_throw(); 
    // ... 
} 
catch(my_exception& e) 
{ 
    e.do_exception_stuff(); 
} 
catch(std::exception& e) 
{ 
    std::cout << e.what(); 
} 
catch(...) 
{ 
    std::cout << "Something bad happened.\n"; 
} 

यह अपवाद फेंकने के लिए ही संभव है आप बेहतर पकड़ कर या पुन: प्रयास करने में विफल रहा है आपरेशन या कुछ और पर योजना नहीं है

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

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