मैं सच में यकीन है कि जब नहीं कर रहा हूँ वास्तव में मैं बनाम गति
तुम हमेशा अपवाद सुरक्षा के लिए प्रयास करना चाहिए अपवाद सुरक्षा के लिए प्रयास करना चाहिए। ध्यान दें कि "अपवाद सुरक्षा" का अर्थ यह नहीं है, "कुछ गलत होने पर अपवाद फेंकना"। इसका मतलब है "तीन अपवाद गारंटीओं में से एक प्रदान करना: कमजोर, मजबूत या नोट्रो"। अपवाद फेंकना वैकल्पिक है। आपके कोड के कॉलर्स को संतुष्ट होने की अनुमति देने के लिए अपवाद सुरक्षा आवश्यक है कि त्रुटि होने पर उनका कोड सही ढंग से कार्य कर सके।
आप अपवादों के संबंध में विभिन्न सी ++ प्रोग्रामर/टीमों से बहुत अलग शैलियों को देखेंगे। कुछ लोग उन्हें बहुत अधिक उपयोग करते हैं, दूसरों को शायद ही कभी (या यहां तक कि सख्ती से भी नहीं, हालांकि मुझे लगता है कि यह काफी दुर्लभ है। Google शायद सबसे अधिक (इन) प्रसिद्ध उदाहरण है, यदि आप रुचि रखते हैं तो उनके कारणों के लिए उनकी सी ++ शैली मार्गदर्शिका देखें एम्बेडेड डिवाइस और गेम के अंदरूनी भाग शायद सी ++ में अपवादों से परहेज करने वाले लोगों के उदाहरण ढूंढने के लिए अगली सबसे संभावित जगहें हैं। मानक iostreams लाइब्रेरी आपको धाराओं पर ध्वज सेट करने देती है कि क्या I/O त्रुटियों के दौरान उन्हें अपवाद फेंकना चाहिए। डिफ़ॉल्ट पर है, जो लगभग किसी अन्य भाषा से प्रोग्रामर को आश्चर्यचकित करता है जिसमें अपवाद मौजूद हैं।
क्या सूची में असफल होने पर मुझे वास्तव में कोई त्रुटि फेंकनी चाहिए?
यह "सूची" असफल नहीं है, यह विशेष रूप से pop_front
कहा जाता है जब सूची खाली होती है जो विफल हो जाती है। आप कक्षा पर सभी परिचालनों पर सामान्यीकृत नहीं कर सकते हैं, कि उन्हें हमेशा विफलता पर अपवाद फेंकना चाहिए, आपको विशिष्ट मामलों पर विचार करना होगा।इस मामले में आपके पास कम से कम पांच उचित विकल्प हैं:
- यह इंगित करने के लिए एक मूल्य लौटाता है कि कुछ भी पॉप किया गया था या नहीं। कॉलर कुछ भी ऐसा कर सकता है जिसे वे पसंद करते हैं, या इसे अनदेखा करते हैं।
- दस्तावेज़ यह है कि सूची खाली होने पर
pop_front
पर कॉल करने के लिए अपरिभाषित व्यवहार है, फिर pop_front
के लिए कोड में संभावना को अनदेखा करें। यह एक खाली मानक कंटेनर पॉप करने के लिए यूबी है, और कुछ मानक लाइब्रेरी कार्यान्वयन में कोई जांच कोड नहीं है, खासकर रिलीज बिल्ड में।
- दस्तावेज़ कि यह अपरिभाषित व्यवहार है, लेकिन फिर भी जांच करें, और या तो प्रोग्राम को रोक दें, या अपवाद फेंक दें। आप शायद डीबग बिल्ड (जो
assert
के लिए है) में चेक कर सकते हैं, इस मामले में आपके पास डीबगर ब्रेकपॉइंट ट्रिगर करने का विकल्प भी हो सकता है।
- दस्तावेज़ कि यदि सूची खाली है, तो कॉल का कोई प्रभाव नहीं पड़ता है।
- दस्तावेज़ कि सूची खाली होने पर अपवाद फेंक दिया गया है।
इन सभी में से आखिरी मतलब यह है कि आपका कार्य "नोट्रो" गारंटी प्रदान कर सकता है। आप जो भी चुनते हैं वह इस बात पर निर्भर करता है कि आप अपनी एपीआई को किस तरह दिखाना चाहते हैं, और आप अपनी कॉलर्स को अपनी बग खोजने में किस तरह की मदद देना चाहते हैं। ध्यान दें कि एक अपवाद फेंकने आपके तत्काल कॉलर को पकड़ने के लिए मजबूर नहीं करता है। अपवाद केवल कोड द्वारा पकड़ा जाना चाहिए जो त्रुटि से पुनर्प्राप्त करने में सक्षम है (या वैकल्पिक रूप से कार्यक्रम के शीर्ष पर)।
व्यक्तिगत रूप से, मैं उपयोगकर्ता त्रुटियों के लिए अपवाद फेंकने की ओर झुकता हूं, और मैं यह भी कहने की ओर झुकता हूं कि एक खाली सूची पॉपिंग उपयोगकर्ता त्रुटि है। इसका मतलब यह नहीं है कि डीबग मोड में सभी प्रकार के चेक होने के लिए उपयोगी नहीं है, सिर्फ यह कि मैं आमतौर पर ऐसे चेक की गारंटी देने के लिए एपीआई को परिभाषित नहीं करता हूं, सभी मोड में किया जाएगा।
नहीं, यह नहीं आवश्यक, क्योंकि यह एक परिहार्य त्रुटि है एक कस्टम त्रुटि वर्ग वास्तव में ऐसी बात के लिए आवश्यक है। एक कॉलर हमेशा यह सुनिश्चित कर सकता है कि pop_front
पर कॉल करने से पहले सूची खाली नहीं है, यह जांच कर इसे फेंक दिया नहीं जाएगा। std::logic_error
फेंकने के लिए एक बिल्कुल उचित अपवाद होगा। एक विशेष अपवाद वर्ग का उपयोग करने का मुख्य कारण यह है कि कॉलर केवल उस अपवाद को पकड़ सकते हैं: यह आपके ऊपर निर्भर करता है कि क्या आपको लगता है कि कॉलर्स को किसी विशेष मामले के लिए ऐसा करने की आवश्यकता होगी।
क्या यह सिर के लिए संभव है _-> 0 को असाइन करते समय कभी फेंक दिया जाता है?
जब तक आपके प्रोग्राम ने किसी भी तरह से अपरिभाषित व्यवहार को उकसाया नहीं है। तो हाँ, आप इससे पहले आकार घटा सकते हैं, और आप इसे delete
से पहले घटा सकते हैं बशर्ते आप सुनिश्चित हैं कि ListElem का विनाशक फेंक नहीं सकता है। और जब कोई विनाशक लिखते हैं, तो आपको यह सुनिश्चित करना चाहिए कि यह फेंक न जाए।
मैं अक्सर सुनता हूं कि एक सी ++ प्रोग्राम में कुछ भी असफल हो सकता है। क्या का परीक्षण करना यथार्थवादी है यदि ListElem के निर्माता (या न्यूज़ के दौरान tail_) विफल रहता है?
यह सच नहीं है कि सबकुछ विफल हो सकता है।आदर्श रूप से कार्यों को दस्तावेज करना चाहिए कि वे किस अपवाद गारंटी की पेशकश करते हैं, जो बदले में आपको बताता है कि वे फेंक सकते हैं या नहीं। यदि वे वास्तव में अच्छी तरह से प्रलेखित हैं, तो वे जो कुछ भी फेंक सकते हैं, वे सूचीबद्ध करेंगे, और किस परिस्थिति में वे इसे फेंक देते हैं।
आप नहीं परीक्षणnew
कि क्या विफल रहता है चाहिए, तो आप अपने फोन करने वाले को अपने कार्य से प्रचार करने के लिए new
से अपवाद की अनुमति चाहिए, यदि कोई हो,। फिर आप केवल push_front
मेमोरी की कमी का संकेत देने के लिए std::bad_alloc
फेंक सकते हैं, और शायद यह भी कि T
(int
के मामले में कुछ भी नहीं) के प्रतिलिपि द्वारा फेंक दिया गया कुछ भी फेंक सकता है। आपको प्रत्येक फ़ंक्शन के लिए इसे अलग से दस्तावेज़ करने की आवश्यकता नहीं हो सकती है - कभी-कभी कई कार्यों को कवर करने वाला एक सामान्य नोट पर्याप्त होता है। यह किसी को भी आश्चर्यचकित नहीं होना चाहिए कि अगर push_front
नामक एक फ़ंक्शन फेंक सकता है, तो इसे फेंकने वाली चीज़ों में से एक bad_alloc
है। यह टेम्पलेट कंटेनर के उपयोगकर्ताओं के लिए आश्चर्यचकित नहीं होना चाहिए, यदि निहित तत्व अपवाद फेंकते हैं, तो उन अपवादों का प्रचार किया जा सकता है।
यह कभी डेटा की प्रकार का परीक्षण करने के लिए आवश्यक होगा यकीन प्रकार संरचना के लिए व्यवहार्य है बनाने के लिए (वर्तमान में एक सरल typedef int टी जब तक मैं सब कुछ templatize)?
आप शायद अपनी संरचना लिख सकते हैं जैसे टी की सभी आवश्यक है कि यह प्रति-रचनात्मक और असाइन करने योग्य है। इसके लिए विशेष परीक्षण जोड़ने की कोई आवश्यकता नहीं है - अगर कोई आपके टेम्पलेट को उस प्रकार के साथ चालू करने का प्रयास करता है जो आपके द्वारा किए गए संचालन का समर्थन नहीं करता है, तो उन्हें संकलन त्रुटि मिल जाएगी। हालांकि, आपको आवश्यकताओं को दस्तावेज करना चाहिए।
मुझे लगता है कि 'push_back' में एक बग है। सूची खाली होने पर यह दो बार सूची में 'डेटा' डालती है, लेकिन केवल एक बार 'आकार' में वृद्धि होती है ... –
हां, निश्चित रूप से वहां 'अन्य' और कुछ ब्रेसिज़ गायब हैं। ;) मेरा जवाब इस धारणा पर लिखा गया है कि यह तय हो जाता है। –
+1। इस सवाल को फिर से बनाया जाना चाहिए और सी ++ - faq टैग में डाल दिया जाना चाहिए। अधिकांश लोगों को या तो कोई अपवाद नहीं है कि अपवाद सुरक्षा क्या है, या इसके बारे में गलत धारणाएं हैं, और अन्य शायद उनकी याददाश्त को ताज़ा करना चाहेंगे। –