2013-07-01 10 views
15
A:  catch(...) 
B:  catch(std::exception& e) 

प्रश्न के बीच अंतर यह है कि एक पकड़ क्या हो सकता है लेकिन बी नहीं कर सकता है।std :: अपवाद और "..."

और C++ एक सार्वभौमिक जड़ अपवाद है कि कुछ भी पकड़ सकते हैं

शुरू की नहीं है क्यों --- जोड़ा मैं माफी चाहता, मैंने कहा जाना चाहिए था रहा हूँ कि मैं सी में समझ में ++ आप पूर्णांक की तरह किसी भी प्रकार फेंक दिया सकता है, लेकिन इसके अलावा, और क्या फेंक दिया जा सकता है?

मेरी समस्या यह है कि मैं यह पता लगाने की कोशिश कर रहा हूं कि कोड से कौन सा अपवाद फेंक दिया गया है, जिसे ए द्वारा पकड़ा जा सकता है लेकिन बी नहीं। यह अपवाद निश्चित रूप से "int" जैसा नहीं है। यह एक सिस्टम अपवाद या स्मृति उल्लंघन प्रकार की तरह होना चाहिए। मैं बस सोच रहा हूं कि यह क्या हो सकता है।

+0

सी ++ सब है कि एक 'जड़' अपवाद प्रकार नहीं है अपवादों का उत्तराधिकारी होता है क्योंकि सी ++ कुछ भी फेंक सकता है, जिसमें वे प्रकार शामिल नहीं हो सकते हैं; जैसे 'Int'। सी ++ कुछ भी फेंक सकता है क्योंकि उन्हें अपवाद कम सामान्य बनाने का कोई कारण नहीं दिखता था। यह सी ++ टेम्पलेट्स के समान है; सी ++ टेम्पलेट्स विरासत पर भरोसा नहीं करते हैं और इसलिए जावा या सी # जेनेरिक से अधिक सामान्य हैं जो विरासत पर भरोसा करते हैं। – bames53

+1

कुछ विंडोज एसईएच अपवाद कभी-कभी '...' द्वारा पकड़े जा सकते हैं लेकिन 'std :: अपवाद 'द्वारा नहीं। –

+0

@MooingDuck केवल तभी आप पागल झंडे के साथ संकलित करते हैं, अनुशंसित/ईएचएससी (यदि आप कर सकते हैं) का उपयोग करें और आप ठीक होंगे –

उत्तर

28

catch (...) एक तथाकथित "पकड़ो सभी" ब्लॉक है। यह किसी भी सी ++ अपवाद को पकड़ लेगा।

catch(std::exception& e)केवल अपवाद जो std::exception से प्राप्त किए गए अपवादों को पकड़ेंगे।

यहाँ एक अपवाद है कि कैच-ऑल द्वारा बुलाया जाएगा का एक उदाहरण है, लेकिन नहीं दूसरे संस्करण:

throw 42; 

यह आप के लिए अजीब लग सकता है, और यह है। एहसास करने की महत्वपूर्ण बात यह है कि कुछ भी को सी ++ अपवाद के रूप में फेंक दिया जा सकता है - न केवल exception एस या exception से ली गई चीजें। चूंकि @ bames53 टिप्पणियों में उल्लेख करता है, वहां कोई रूट अपवाद प्रकार नहीं है जो सभी अपवादों से लिया गया है, जैसे कि कुछ अन्य भाषाओं में है।

यह भी ध्यान रखना महत्वपूर्ण है कि एक कैच-ऑल ब्लॉक दुरुपयोग के लिए बहुत आसान है। वास्तव में, अंगूठे के सामान्य नियम के रूप में यह मानना ​​सबसे अच्छा हो सकता है कि सभी पकड़-सभी ब्लॉक प्रोग्राम दोष हैं। बेशक, प्रोग्रामिंग में "हमेशा" नहीं है, लेकिन जब आप अपवादों का उपयोग करना सीख रहे हैं तो यह एक सुरक्षित धारणा है।

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


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

अपवाद को रेथ्रो करना करना आसान है। सीधे शब्दों में कोई तर्क के साथ throw कहते हैं, के साथ के रूप में:

catch (...) 
{ 
    // some magic 
    throw; 
} 

ध्यान में रखने की एक और बात यह है कि जब आप एक अपवाद को पकड़ने करते हैं, यह आम तौर पर सबसे अच्छा है सिर्फ एक संदर्भ की तुलना में एक const संदर्भ को पकड़ने के लिए है, न कि है ।

+5

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

+0

@MatteoItalia: क्या आप इसके बारे में निश्चित हैं? यह लंबे समय से रहा है क्योंकि मैंने एसईएच के साथ निपटाया है और आप शायद सही हैं, लेकिन मुझे यह याद नहीं है। –

+0

मुझे पुराने डिफ़ॉल्ट व्यवहार के बारे में निश्चित नहीं है, लेकिन आप निश्चित रूप से एसईएच अपवादों को पकड़ने में सक्षम होने के लिए सेटिंग बदल सकते हैं। – jerry

1

कैसे int एस?

try { 
    throw 123; 
} catch (std::exception &e) { 
    // this won't catch 
} catch (...) { 
    // this will catch 
} 
2

संक्षिप्त उत्तर इसकी (सार्वजनिक) विरासत पदानुक्रम में std::exception के बिना कुछ भी है:

#include <exception> 
#include <iostream> 

int main() 
{ 
    try 
    { 
     throw false; 
    } 
    catch(std::exception& e) 
    { 
     std::cout << "Caught std::exception" << std::endl; 
    } 
    catch(...) 
    { 
     std::cout << "Caught something else" << std::endl; 
    } 

    return 0; 
} 

आउटपुट:

Caught something else
संबंधित मुद्दे