क्या आप में पकड़ा जा रहा है लगता है कि किसी को अपने केक है और यह भी खाने की कोशिश कर के विशिष्ट नरक है।
RAII और अपवादों को हाथ से जाने के लिए डिज़ाइन किया गया है। RAII वह साधन है जिसके द्वारा आपको सफाई करने के लिए बहुत सारे कथन लिखने की आवश्यकता नहीं हैcatch(...)
। यह स्वचालित रूप से होगा, निश्चित रूप से। और अपवाद आरएआईआई वस्तुओं के साथ काम करने का एकमात्र तरीका है, क्योंकि निर्माणकर्ता केवल सफल या वस्तु को एक त्रुटि स्थिति में डाल सकते हैं या फेंक सकते हैं, लेकिन कौन चाहता है?)।
एक catch
बयान दो चीजों में से एक कर सकता है: एक त्रुटि या असाधारण परिस्थिति को संभालना, या सफाई का काम करना। कभी-कभी यह दोनों करता है, लेकिन catch
इनमें से कम से कम एक करने के लिए प्रत्येक कथन मौजूद है।
catch(...)
उचित अपवाद हैंडलिंग करने में असमर्थ है। आप नहीं जानते कि अपवाद क्या है; आपको अपवाद के बारे में जानकारी नहीं मिल सकती है। आपके पास इस तथ्य के अलावा पूरी तरह से कोई जानकारी नहीं है कि एक निश्चित कोड ब्लॉक के भीतर कुछ अपवाद द्वारा फेंका गया था । इस तरह के ब्लॉक में आप केवल एक वैध काम कर सकते हैं। और इसका मतलब है कि सफाई के अंत में अपवाद को फिर से फेंकना।
आरएआई आपको अपवाद हैंडलिंग के संबंध में क्या देता है, निशुल्क सफाई है। यदि सब कुछ आरएआई ठीक से समझाया जाता है, तो सब कुछ ठीक से साफ हो जाएगा। अब आपको catch
कथन सफाई करने की आवश्यकता नहीं है । किस मामले में, एक catch(...)
बयान लिखने का कोई कारण नहीं है ।
तो मैं सहमत हूँ कि catch(...)
ज्यादातर बुराई है ... अनंतिम रूप से ।
यह प्रावधान RAII का उचित उपयोग है। क्योंकि इसके बिना, आपको कुछ सफाई करने में सक्षम होने की आवश्यकता है। इसके आसपास कोई नहीं मिल रहा है; आपको सफाई कार्य करने में सक्षम होना चाहिए। आपको यह सुनिश्चित करने में सक्षम होना चाहिए कि एक अपवाद को फेंकने से कोड एक उचित स्थिति में निकल जाएगा। और catch(...)
ऐसा करने में एक महत्वपूर्ण उपकरण है।
आप एक के बिना दूसरा नहीं रख सकते है। आप यह नहीं कह सकते हैं कि दोनों RAII और catch(...)
खराब हैं। आपको इनमें से कम से कम एक की आवश्यकता है; अन्यथा, आप सुरक्षित नहीं हैं।
बेशक, वहाँ एक वैध-हालांकि-दुर्लभ उपयोग है catch(...)
कि RAII भी नहीं मिट सकता है: exception_ptr
किसी और को आगे करने के लिए। आमतौर पर एक promise/future
या समान इंटरफ़ेस के माध्यम से ।
मेरे सहकर्मियों का कहना है कि आपको हमेशा पता होना चाहिए कि किन अपवादों को फेंकना है और आप हमेशा जैसे निर्माण का उपयोग कर सकते हैं:
आपका सहकर्मी एक मूर्ख (या सिर्फ बहुत अज्ञानी) है। यह तुरंत स्पष्ट होना चाहिए कि वह कितना कॉपी-एंड-पेस्ट कोड बता रहा है, जो आप लिखते हैं। उन कैच स्टेटमेंट्स में से प्रत्येक के लिए क्लीनअप बिल्कुल समान होगा । यह एक दुःस्वप्न है, पठनीयता का उल्लेख नहीं है।
संक्षेप में: यह वह समस्या है जिसे आरएआईआई ने हल करने के लिए बनाया था (यह नहीं कि यह अन्य समस्याओं को हल नहीं करता है)।
इस धारणा के बारे में मुझे क्या भ्रम है कि यह आमतौर पर पीछे की ओर है कि ज्यादातर लोग यह तर्क देते हैं कि RAII खराब है। आम तौर पर, तर्क यह है कि "RAII खराब है क्योंकि आपको निर्माण विफलता का संकेत करने के लिए अपवादों का उपयोग करना है। लेकिन आप अपवादों को फेंक नहीं सकते हैं, क्योंकि यह सुरक्षित नहीं है और आपको catch
सब कुछ साफ करने के लिए बहुत सारे बयान देने होंगे।" जो एक टूटा हुआ तर्क है क्योंकि RAII उस समस्या को हल करता है जो RAII की कमी पैदा करती है।
संभावना से अधिक, वह RAII के खिलाफ है क्योंकि यह विवरण छुपाता है। विध्वंसक कॉल स्वचालित चर पर तुरंत दिखाई नहीं देते हैं। तो आपको कोड मिलता है जिसे अव्यक्त रूप से कहा जाता है। कुछ प्रोग्रामर वास्तव में नफरत करते हैं। जाहिरा तौर पर, उस बिंदु पर जहां उन्हें लगता है कि 3 catch
कथन हैं, जो सभी कॉपी-एंड-पेस्ट कोड के साथ एक ही काम करते हैं, एक बेहतर विचार है।
...
जबकि मेरा प्रश्न "क्या मुझे बेहतर पकड़ना चाहिए...
या फिर<specific exception>
से पहले फेंकना चाहिए"