2008-09-11 17 views
10

सी ++ में, मैं एक पकड़ में सभी प्रकार के अपवादों को पकड़ने की कोशिश कर रहा हूं (जैसे सी # में catch(Exception))। यह कैसे किया जाता है? और और भी, कैसे विभाजित-शून्य-अपवादों को विभाजित कर सकते हैं?मैं एक कैच ब्लॉक में सभी प्रकार के अपवाद कैसे पकड़ सकता हूं?

उत्तर

23
catch (...) 
{ 
    // Handle exceptions not covered. 
} 

महत्वपूर्ण विचार:

  • एक बेहतर दृष्टिकोण है कि आप वास्तव में के रूप में सभी संभव अपवाद का विरोध करने से ठीक हो सकता है अपवाद के विशिष्ट प्रकार के पकड़ने के लिए है।
  • पकड़ (...) कुछ गंभीर सिस्टम स्तर अपवाद भी प्राप्त करेगा (कंपाइलर के आधार पर भिन्न होता है) कि आप विश्वसनीय रूप से पुनर्प्राप्त करने में सक्षम नहीं होंगे। उन्हें इस तरह से पकड़ना और फिर उन्हें निगलना और जारी रखना आपके कार्यक्रम में और गंभीर समस्याएं पैदा कर सकता है।
  • आपके संदर्भ के आधार पर यह पकड़ (...) का उपयोग करने के लिए स्वीकार्य हो सकता है, अपवाद प्रदान करने को फिर से फेंक दिया जाता है। इस मामले में, आप सभी उपयोगी स्थानीय राज्य की जानकारी लॉग करते हैं और फिर अपवाद को फिर से फेंक देते हैं ताकि इसे प्रसारित किया जा सके। हालांकि यदि आप इस मार्ग को चुनते हैं तो आपको RAII pattern पर पढ़ना चाहिए।
+0

नहीं कर सकते यह MySQL त्रुटियों (कुंजी नकल) को पकड़ने के लिए मिलता है ... –

3

अपने सभी कस्टम अपवाद वर्गों को std :: अपवाद से प्राप्त करें, तो आप बस std :: अपवाद को पकड़ सकते हैं। यहाँ कुछ उदाहरण कोड है:

class WidgetError 
    : public std::exception 
{ 
public: 
    WidgetError() 
    { } 

    virtual ~WidgetError() throw() 
    { } 

    virtual const char *what() const throw() 
    { 
     return "You got you a widget error!"; 
    } 
}; 
+0

इस आदेश पकड़ ब्लॉक के gobs कम करने के लिए अच्छा अभ्यास है जैसा कि दूसरों ने नोट किया है (...) आमतौर पर असुरक्षित है। Std :: अपवाद एक यूनिकोड के तहत संकलन करते समय थोड़ा गन्दा है। (क्योंकि क्या() एक char स्ट्रिंग देता है, wchar_t स्ट्रिंग नहीं) – seand

0

अगर मैं सही ढंग याद (यह कुछ समय के बाद से मैं सी ++ देखा है हो गया है), मुझे लगता है कि चाल

try 
{ 
// some code 
} 
catch(...) 
{ 
// catch anything 
} 

और एक त्वरित गूगल करना चाहिए निम्नलिखित (http://www.oreillynet.com/pub/a/network/2003/05/05/cpluspocketref.html) मुझे सही साबित करने लगता है।

+0

विंडोज़ में संभावित रूप से असुरक्षित और संभवतः अन्य। यह प्रवेश उल्लंघन और अन्य वास्तव में खराब घटनाओं को झुकाता है। – seand

1

सी ++ में, मानक विभाजित-द्वारा-शून्य अपवाद को परिभाषित नहीं करता है, और कार्यान्वयन उन्हें फेंक नहीं देते हैं।

14

आप पकड़ (...) (यानी इलिप्सिस के साथ पकड़ना) का उपयोग करना चाहते हैं, जब तक कि आप वास्तव में, निश्चित रूप से, सबसे अधिक सिद्ध करने की आवश्यकता नहीं होती है।

इसका कारण यह है कि कुछ कंपाइलर्स (विज़ुअल सी ++ 6 सबसे आम नाम देने के लिए 6) सेगमेंटेशन दोषों और अन्य वास्तव में खराब स्थितियों जैसे त्रुटियों को भी अपवाद में बदलते हैं जिन्हें आप खुशी से पकड़ (...) का उपयोग करके संभाल सकते हैं। यह बहुत बुरा है, क्योंकि अब आप दुर्घटनाओं को नहीं देखते हैं।

और तकनीकी रूप से, हाँ, आप शून्य से विभाजन भी पकड़ सकते हैं (आपको इसके लिए "स्टैक ओवरफ्लो" करना होगा), लेकिन आपको वास्तव में ऐसे डिवीजनों को पहले स्थान पर टालना चाहिए।

इसके बजाय

, निम्न करें:

  • आप वास्तव में अपवाद (रों) किस तरह की उम्मीद पता है, उन प्रकार के और अधिक नहीं पकड़ रहे हैं, तो और
  • आप अपवाद अपने आप को फेंक की जरूरत है, और उन सभी अपवादों को पकड़ने की आवश्यकता है जिन्हें आप फेंक देंगे, इन अपवादों को std :: अपवाद से प्राप्त करें (जैसे एडम पियर्स ने सुझाव दिया) और इसे पकड़ें।
4

यदि सभी अपवादों को पकड़ना - ओएस सहित - वास्तव में आपको जो चाहिए, आपको अपने कंपाइलर और ओएस को देखने की आवश्यकता है। उदाहरण के लिए, विंडोज़ पर आपके पास शायद "__try" कीवर्ड या कंपाइलर स्विच "एसईएच अपवाद" या दोनों को पकड़ने के लिए "कोशिश/पकड़" बनाने के लिए है।

+0

ईबेल गिल: धन्यवाद, आपके उत्तर में बहुत मदद मिली! – gil

1

आप निश्चित रूप से catch (...) { /* code here */ } का उपयोग कर सकते हैं, लेकिन यह वास्तव में उस पर निर्भर करता है जो आप करना चाहते हैं। सी ++ में आपके पास निर्धारक विनाशक (उस अंतिमकरण में से कोई भी बकवास नहीं है), इसलिए यदि आप ऊपर उठना चाहते हैं, तो सही काम करने के लिए आरएआईआई का उपयोग करना है।

उदाहरण के लिए। के बजाय:

#include<boost/shared_ptr.hpp> 

void my_func() 
{ 
    boost::shared_ptr<void> h(get_handle_that_must_be_released(), release_object); 
    random_func(h.get()); 
} 

एक नाशक के साथ अपने स्वयं कक्षा बनाएं अगर आप को बढ़ावा देने का उपयोग नहीं करते:

void myfunc() 
{ 
    void* h = get_handle_that_must_be_released(); 
    try { random_func(h); } 
    catch (...) { release_object(h); throw; } 
    release_object(h); 

} 

की तरह कुछ करो।

5

यदि आप विंडोज़ पर हैं और शून्य से विभाजित करने और उल्लंघन का उपयोग करने जैसी त्रुटियों को संभालने की आवश्यकता है तो आप एक संरचित अपवाद अनुवादक का उपयोग कर सकते हैं। ,

void myTranslator(unsigned code, EXCEPTION_POINTERS*) 
{ 
    throw std::exception(<appropriate string here>); 
} 

_set_se_translator(myTranslator); 

नोट कोड आपको बता देंगे क्या त्रुटि थी: और फिर अपने अनुवादक के अंदर आप एक सी ++ अपवाद फेंक कर सकते हैं। इसके अलावा आपको/ईएचए विकल्प (सी/सी ++ -> कोड जेनरेट्रियन -> सी/सी ++ अपवादों = एसईएच अपवादों के साथ सक्षम करें) के साथ संकलित करने की आवश्यकता है।

उस अर्थ चेकआउट नहीं आता, तो [_set_se_translator] के लिये दस्तावेज (http://msdn.microsoft.com/en-us/library/5z4bw5h5(VS.80).aspx)

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