2010-03-26 13 views
67

संभव डुप्लिकेट:
catch exception by pointer in C++सी ++ पकड़ ब्लॉक - मूल्य या संदर्भ द्वारा अपवाद पकड़ो?

मैं हमेशा मूल्य द्वारा अपवाद को पकड़ने के। उदाहरण के लिए:

try{ 
... 
} 
catch(CustomException e){ 
... 
} 

लेकिन मैं कुछ कोड है कि बजाय catch(CustomException &e) बजाय था भर में आया था। क्या यह एक है) ठीक बी) गलत सी) एक ग्रे क्षेत्र?

+0

ध्यान दें कि सही संदर्भ भी स्थिर है: 'पकड़ (कस्टम अपवाद कॉन्स और ई) ' –

+1

डुप्लिकेट के रूप में चिह्नित नहीं किया जाना चाहिए - पकड़ना पीआरटी द्वारा अपवाद संदर्भ या मूल्य से पकड़ने से अलग है। – wcochran

उत्तर

103

सी ++ में अपवाद के लिए मानक अभ्यास है ...

संदर्भ

मूल्य द्वारा पकड़ने से फेंक मूल्य, पकड़ से विरासत पदानुक्रम का सामना करने में समस्याग्रस्त है। मान लीजिए कि आपके उदाहरण के लिए MyException एक और प्रकार है जो CustomException से प्राप्त होता है और त्रुटि कोड जैसे आइटम ओवरराइड करता है। यदि MyException प्रकार को फेंक दिया गया था तो आपका कैच ब्लॉक इसे CustomException उदाहरण में परिवर्तित कर देगा जिससे त्रुटि कोड बदल जाएगा। catch (const CustomException& e) { ... }:

संदर्भ

+4

बुला रहे हैं इस में मैं जोड़ना होगा: कॉन्स्ट संदर्भ द्वारा पकड़ो। दुर्भाग्यवश आप एक कॉन्स ऑब्जेक्ट फेंक सकते हैं और इसे गैर-कॉन्स्ट संदर्भ के साथ पकड़ सकते हैं। इस शांत "कास्टिंग" को रोकने के लिए, हमेशा एक कॉन्स्ट संदर्भ प्राप्त करें, और सुनिश्चित करें कि आपके अपवाद प्रकारों में कॉन्स्ट-सही एक्सेसर्स हैं। –

+20

@ डैनियल ईरविकियर: यह "दुर्भाग्यपूर्ण" क्यों है कि आप एक गैर-कॉन्स्ट संदर्भ के माध्यम से पकड़ सकते हैं? अपवाद ऑब्जेक्ट हमेशा कॉपी किया जाता है, जो भी आप 'ऑब्जेक्ट' फेंकते हैं, आप किसी भी कैच ब्लॉक से मूल को प्रभावित नहीं कर सकते क्योंकि 'ऑब्जेक्ट' फेंकना वास्तव में केवल प्रारंभकर्ता था। कॉन्स से दूर कास्टिंग नहीं है; अपवाद वस्तुएं हमेशा गैर-स्थिर, गैर-अस्थिर होती हैं। गैर-कॉन्स्ट संदर्भ के माध्यम से पकड़ने की अनुमति देने से अपवाद में जानकारी जोड़ने के लिए इंटरमीडिएट कैच ब्लॉक सक्षम होते हैं। इसका आमतौर पर उपयोग नहीं किया जाता है लेकिन यदि आपको इसकी आवश्यकता होती है तो यह वहां होता है। –

+0

यदि आप स्वीकृत उत्तर चाहते हैं तो कृपया एक संदर्भ प्रदान कर सकते हैं :) –

20

मूल्य से पकड़ना स्लाइस अपवाद ऑब्जेक्ट है यदि अपवाद आपके द्वारा प्राप्त किए गए प्रकार के व्युत्पन्न प्रकार का अपवाद है।

यह आपके पकड़ ब्लॉक में तर्क के लिए कोई फर्क नहीं पड़ता है, लेकिन कॉन्स संदर्भ द्वारा पकड़ने के लिए कोई कारण नहीं है।

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

+6

मैं इस संदर्भ में * स्लाइस * शब्द से परिचित नहीं हूं। –

+6

मुझे लगता है कि "टुकड़ा" एक शब्द है जो लोग उपयोग करने के लिए संदर्भित भाषाओं को संदर्भित करने के लिए उपयोग किए जाते हैं। विचार यह है कि यदि आप व्युत्पन्न वस्तु को अपने मूल प्रकार पर निर्दिष्ट करते हैं, तो मुझे ऑब्जेक्ट का हिस्सा "टुकड़ा करना" है, जो मुझे देखने के लिए एक भ्रामक तरीके जैसा लगता है क्योंकि वास्तव में क्या हो रहा है कि बेस क्लास की कॉपी असाइनमेंट ऑपरेटर में ' आधार और ऑपरेटर = (आधार आधार और अन्य) 'व्युत्पन्न वस्तु को स्पष्ट रूप से' आधार 'संदर्भ में परिवर्तित किया जा रहा है, इसलिए असाइनमेंट व्युत्पन्न वर्ग को बेस क्लास के समान ही मानता है।कोई जादू slicing-up या सामान स्थानांतरित नहीं है, आप एक समारोह – Injektilo

8

जब तक आप अपवाद के साथ बेला के लिए चाहते हैं, तो आप आमतौर पर एक स्थिरांक संदर्भ का उपयोग करना चाहिए। कंपाइलर फेंक ऑब्जेक्ट के जीवनकाल से संबंधित है।

2

में CustomException की (CustomException e) नई वस्तु बनाई गई है ... तो यह की निर्माता समय में (CustomException & ई) यह सिर्फ संदर्भ ... नहीं नई वस्तु बनाई गई है और कोई निर्माता बुलाया जाएगा होगा बुलाया जाएगा ... तो औपचारिक थोड़ा सा ओवरहेड है ... बाद में उपयोग करने के लिए बेहतर है ...

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