2010-12-19 25 views
10

मैं सिर्फ एक नवाचारी प्रोग्रामर हूं कि कम से कम सर्वश्रेष्ठ केस परिदृश्य से अधिक कार्यक्रम करने की कोशिश करता है। मैं हर्ब सटर के "असाधारण सी ++" पढ़ रहा हूं और अभी तक अपवाद-सुरक्षा अध्यायों के माध्यम से चला गया हूं। हालांकि, उदाहरण को छोड़कर वह एक स्टैक (एक स्टैक) को छोड़कर, मुझे सच में यकीन नहीं है कि वास्तव में मुझे अपवाद सुरक्षा बनाम गति के लिए प्रयास करना चाहिए और जब ऐसा करने के लिए यह केवल सादा मूर्खतापूर्ण है।अपवाद सुरक्षा- कब, कैसे, क्यों?

उदाहरण के लिए, मेरे वर्तमान होमवर्क परियोजना एक दोगुना से जुड़े सूची है। चूंकि मैंने इनमें से कुछ को पहले से प्रोग्राम किया है, इसलिए मैं ईएस जैसी कुछ गहरी अवधारणाओं में शामिल होने के लिए समय लेना चाहता था।

void List::pop_front() 
{ 
    if(!head_) 
     throw std::length_error("Pop front: List is empty.\n"); 
    else 
    { 
     ListElem *temp = head_; 
     head_   = head_->next; 
     head_->prev = 0; 
     delete temp; 
     --size_; 
    } 
} 

मैं इस के साथ कुछ दुविधाओं था:

यहाँ मेरी पॉप-सामने कार्य है।

1) क्या सूची में असफल होने पर मुझे वास्तव में एक त्रुटि फेंकनी चाहिए? कोशिश करने के लिए सूची के उपयोगकर्ता को मजबूर करने के बजाय मैं कुछ भी नहीं करना चाहिए और वापस लौटना नहीं चाहिए {] catch() {} कथन (जो धीमे भी हैं)।

2) कई त्रुटि वर्गों (प्लस ListException मेरे शिक्षक की मांग हम कक्षा में लागू) हैं। क्या एक कस्टम त्रुटि वर्ग ऐसी चीज के लिए वास्तव में जरूरी है, और क्या एक विशिष्ट अपवाद वर्ग का उपयोग करने के लिए कोई सामान्य मार्गदर्शिका है? (उदाहरण के लिए, रेंज, लंबाई और सीमा के लिए सभी को समान रूप से ध्वनि)

3) मैं जानता हूँ कि मैं सभी कि कोड है कि एक अपवाद किया जा दिया है जब तक कार्यक्रम राज्य परिवर्तन नहीं होना चाहिए। यही कारण है कि मैं आकार_ आखिरी में कमी कर रहा हूं। क्या यह वास्तव में इस सरल उदाहरण में आवश्यक है? मुझे पता है कि हटा नहीं सकता है। क्या यह संभव है कि हेड _-> 0 को असाइन करते समय फेंक दिया जाए?

void List::push_back(const T& data) 
{ 
    if(!tail_) 
    { 
     tail_ = new ListElem(data, 0, 0); 
     head_ = tail_; 
    } 
    else 
    { 
    tail_->next = new ListElem(data, 0, tail_); 
    tail_ = tail_->next; 
    } 
    ++size_; 
} 

1) मैंने सुना है अक्सर कि कुछ भी एक सी ++ प्रोग्राम में असफल हो सकता है:

मेरे push_back समारोह (सिर पहले नोड है)। क्या यह परीक्षण करना यथार्थवादी है कि ListElem के लिए निर्माता विफल रहता है (या new आईएनजी के दौरान tail_)?

2) क्या यह सुनिश्चित करने के लिए कि प्रकार संरचना के लिए व्यवहार्य है, डेटा के प्रकार (वर्तमान में एक साधारण typedef int T जब तक मैं सब कुछ templatize) परीक्षण करने के लिए कभी भी आवश्यक हो?

मुझे लगता है कि इन बेहद सरल उदाहरण हैं, पर मैं वर्तमान में केवल जब मैं वास्तव में अच्छा ES अभ्यास करना चाहिए और जब यह नहीं है के रूप में उलझन में हूँ।

+3

मुझे लगता है कि 'push_back' में एक बग है। सूची खाली होने पर यह दो बार सूची में 'डेटा' डालती है, लेकिन केवल एक बार 'आकार' में वृद्धि होती है ... –

+0

हां, निश्चित रूप से वहां 'अन्य' और कुछ ब्रेसिज़ गायब हैं। ;) मेरा जवाब इस धारणा पर लिखा गया है कि यह तय हो जाता है। –

+1

+1। इस सवाल को फिर से बनाया जाना चाहिए और सी ++ - faq टैग में डाल दिया जाना चाहिए। अधिकांश लोगों को या तो कोई अपवाद नहीं है कि अपवाद सुरक्षा क्या है, या इसके बारे में गलत धारणाएं हैं, और अन्य शायद उनकी याददाश्त को ताज़ा करना चाहेंगे। –

उत्तर

4

यह एक लंबा सवाल है। मैं उन सभी प्रश्नों को ले जाऊंगा जो 1) गिने गए हैं।

1) क्या सूची में असफल होने पर मुझे वास्तव में एक त्रुटि फेंकनी चाहिए? कोशिश करने के लिए सूची के उपयोगकर्ता को मजबूर करने के बजाय मैं कुछ भी नहीं करना चाहिए और वापस लौटना नहीं चाहिए {] catch() {} कथन (जो धीमे भी हैं)।

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

1) मैं अक्सर सुनता हूं कि सी ++ प्रोग्राम में कुछ भी असफल हो सकता है।क्या यह परीक्षण करने के लिए यथार्थवादी है कि ListElem के लिए निर्माता विफल रहता है (या newing के दौरान tail_)?

यदि आप स्मृति से बाहर निकलते हैं तो निर्माता उदाहरण के लिए विफल हो सकता है, लेकिन इस मामले में इसे अपवाद फेंकना चाहिए, न कि वापस लौटना चाहिए। इसलिए आपको कन्स्ट्रक्टर विफल होने के लिए स्पष्ट रूप से परीक्षण करने की आवश्यकता नहीं है। अधिक जानकारी के लिए इस सवाल का देखें:

+0

मैं कहूंगा कि दो तरीकों की आपूर्ति करना ठीक है: एक त्रुटि जो जांच और फेंकता है, और जो गति के लिए जाता है। यह भी है कि 'std :: vector' करता है। मैं हमेशा अच्छी त्रुटि जांच पर भरोसा करता हूं, मेरे लिए यह माइक्रो-ऑप्टिमाइज़ेशन की तुलना में शायद 20x अधिक महत्वपूर्ण है। बेशक मैं हमेशा एक उपयुक्त डेटा संरचना का चयन करें। मेरी राय में अधिकांश सी ++ डेवलपर्स और पुस्तक लेखकों ने गति मुद्दे पर बहुत अधिक ध्यान केंद्रित किया है। –

2

मैंने सुना है अक्सर कि कुछ भी एक सी ++ प्रोग्राम में असफल हो सकता है। क्या यह परीक्षण करने के लिए यथार्थवादी है कि ListElem के लिए निर्माता विफल रहता है (या newing के दौरान tail_)?

हां, यह यथार्थवादी है। अन्यथा, यदि आपका प्रोग्राम स्मृति से बाहर हो जाता है और आवंटन विफल रहता है (या कन्स्ट्रक्टर किसी अन्य आंतरिक कारण के लिए विफल रहता है), तो आपको बाद में समस्याएं हो सकती हैं।

असल में, आप को विफलता को संकेत देना चाहिए किसी भी समय जब कोड पूरी तरह से कुछ करने में असमर्थ है, तो यह एपीआई घोषित करता है।

एकमात्र अंतर यह है कि आप विफलता को कैसे संकेत देते हैं - वापसी मूल्य के माध्यम से या अपवाद के माध्यम से। यदि प्रदर्शन विचार मौजूद हैं, तो वापसी मान अपवादों से बेहतर हो सकते हैं। लेकिन दोनों दृष्टिकोणों को कॉलर में विशेष त्रुटि पकड़ने कोड की आवश्यकता होती है।

+0

FWIW, 'शून्य pop_back()' मानक लाइब्रेरी अनुक्रमिक कंटेनर द्वारा उपयोग किया जाने वाला इंटरफ़ेस है। –

1

सवालों के अपने पहले सेट के लिए:

  1. हाँ, आप @ मार्क के जवाब में सभी कारणों के लिए, फेंक देना चाहिए। (उसे +1)
  2. यह वास्तव में आवश्यक नहीं है, लेकिन यह आपके कॉलर्स पर जीवन को बहुत आसान बना सकता है। अपवाद हैंडलिंग के लाभों में से एक यह है कि यह एक स्थान पर एक विशिष्ट वर्ग त्रुटि के साथ निपटने के लिए कोड को स्थानांतरित करता है। एक विशिष्ट अपवाद प्रकार फेंककर, आप अपने कॉलर्स को उस त्रुटि को विशेष रूप से पकड़ने की अनुमति देते हैं, या आपके द्वारा फेंकने वाले विशिष्ट अपवाद के सुपरक्लास को पकड़कर इसके बारे में अधिक सामान्य हो जाते हैं।
  3. आपके else में सभी विवरणों को नोट्रो गारंटी प्रदान करें।

अपने दूसरे सेट के लिए:

  1. नहीं, यह नहीं परीक्षण करने के लिए यथार्थवादी है। आपको कोई जानकारी नहीं है कि अंतर्निहित कन्स्ट्रक्टर क्या फेंक सकता है। यह एक उम्मीद आइटम (यानी std::bad_alloc) हो सकता है या यह कुछ अजीब (यानी int) हो सकता है, और इसलिए एक ही रास्ता आप इसे संभाल सकता एक catch(...) जो बुराई :)

    दूसरी ओर है अंदर यह डाल करने के लिए किया जाएगा हाथ, आपकी मौजूदा विधि पहले ही अपवाद सुरक्षित है, जब तक if ब्लॉक के अंदर बनाई गई डमी एंड नोड आपकी लिंक की गई सूची के विनाशक द्वारा नियुक्त की जाएगी। (यानी new एस के बाद सबकुछ नोट्रो प्रदान करता है)

  2. बस मान लें कि T पर कोई भी ऑपरेशन विनाशक को छोड़कर फेंक सकता है।

8

मैं वास्तव में एक त्रुटि फेंक देना चाहिए जब एक सूची में विफल रहता है?कोशिश करने के लिए सूची के उपयोगकर्ता को मजबूर करने के बजाय मैं कुछ भी नहीं करना चाहिए और वापस लौटना नहीं चाहिए {] catch() {} कथन (जो धीमे भी हैं)।

बिल्कुल अपवाद फेंक दें।

उपयोगकर्ता को पता होना चाहिए कि सूची खाली होने पर क्या हुआ - अन्यथा यह डीबग करने के लिए नरक होगा। उपयोगकर्ता नहीं को कोशिश/पकड़ने के बयान का उपयोग करने के लिए मजबूर किया गया है; अगर अपवाद अप्रत्याशित है (यानी केवल प्रोग्रामर त्रुटि के कारण हो सकता है), तो इसे पकड़ने का प्रयास करने का कोई कारण नहीं है। जब कोई अपवाद बेकार हो जाता है, तो यह std :: समाप्त होता है और यह बहुत उपयोगी व्यवहार है। प्रयास/पकड़ विवरण स्वयं धीमे नहीं होते हैं, वैसे भी; अपवाद की वास्तविक फेंकने और ढेर के अनचाहे होने की लागत क्या है। अपवाद को फेंकने पर लगभग कुछ भी नहीं होता है।

कई त्रुटि वर्ग हैं (साथ ही सूची शिक्षक मेरे शिक्षक की मांग है कि हम कक्षा में लागू हों)। क्या एक कस्टम त्रुटि वर्ग ऐसी चीज के लिए वास्तव में जरूरी है, और क्या एक विशिष्ट अपवाद वर्ग का उपयोग करने के लिए कोई सामान्य मार्गदर्शिका है? (उदाहरण के लिए, रेंज, लंबाई और सीमा सभी ध्वनि समान)

जितना हो सके उतना विशिष्ट हो। अपनी खुद की त्रुटि कक्षाओं का उपयोग करना ऐसा करने का सबसे अच्छा तरीका है। समूह से संबंधित अपवादों के लिए विरासत का उपयोग करें (ताकि कॉलर उन्हें अधिक आसानी से पकड़ सकें)।

मुझे पता है कि मुझे प्रोग्राम स्थिति को तब तक नहीं बदला जाना चाहिए जब तक कि उस अपवाद को फेंकने वाले सभी कोड नहीं किए जाते। यही कारण है कि मैं आकार_ आखिरी में कमी कर रहा हूं। क्या यह वास्तव में इस सरल उदाहरण में आवश्यक है? मुझे पता है कि हटा नहीं सकता है। क्या यह संभव है कि हेड _-> 0 को असाइन करते समय फेंक दिया जाए? (सिर पहले नोड है)

तो head_ रिक्त है, तो यह अपसंदर्भन (head_->prev को सौंपे जाने के प्रयास का हिस्सा है) अपरिभाषित व्यवहार है। अपवाद फेंकना अपरिभाषित व्यवहार का एक संभावित परिणाम है, लेकिन एक असंभव व्यक्ति (इसके लिए कंपाइलर को अपना हाथ पकड़ने के तरीके से बाहर निकलने की आवश्यकता होती है, ऐसी भाषा में जहां उस तरह की चीज़ बेतुका माना जाता है;), और एक नहीं कि हम इस बारे में चिंता करते हैं, क्योंकि अपरिभाषित व्यवहार अपरिभाषित व्यवहार है - इसका मतलब है कि आपका प्रोग्राम पहले से ही गलत है, और जिस तरीके से यह गलत है, उसे सही बनाने का प्रयास करने में कोई बात नहीं है।

प्लस, आप पहले ही स्पष्ट रूप से जांच कर रहे हैं कि head_ वैसे भी शून्य नहीं है। इसलिए कोई समस्या नहीं है, मान लीजिए कि आप थ्रेडिंग के साथ कुछ भी नहीं कर रहे हैं।

मैं अक्सर सुनता हूं कि सी ++ प्रोग्राम में कुछ भी असफल हो सकता है।

यह थोड़ा पागल है। :)

क्या यह परीक्षण करने के लिए यथार्थवादी है कि ListElem के निर्माता (या new_ के दौरान tail_) विफल रहता है?

यदि new विफल रहता है, तो std::bad_alloc का एक उदाहरण फेंक दिया जाता है। अपवाद फेंकना ठीक है जो आप यहां करना चाहते हैं, इसलिए आप कुछ भी नहीं करना चाहते हैं या कुछ भी करने की ज़रूरत है - बस इसे प्रचारित करें। किसी प्रकार की सूची अपवाद के रूप में त्रुटि का पुन: वर्णन करना वास्तव में उपयोगी जानकारी नहीं जोड़ रहा है और केवल चीजों को अस्पष्ट कर सकता है।

यदि कन्स्ट्रक्टर ListElem विफल रहता है, तो अपवाद को अपवाद करके विफल होना चाहिए, और यह लगभग 99 9 से 1 है कि आपको इसे भी गिरने देना चाहिए।

कुंजी यहां जब भी कोई अपवाद यहाँ फेंक दिया जाता है, वहाँ करने के लिए कोई सफाई काम है कि, क्योंकि आप अभी भी सूची संशोधित नहीं किया है, और निर्माण/newed वस्तु आधिकारिक तौर पर अस्तित्व कभी (टीएम) है। बस सुनिश्चित करें कि इसके निर्माता अपवाद-सुरक्षित है, और आप ठीक होंगे। यदि new कॉल स्मृति आवंटित करने में विफल रहता है, तो कन्स्ट्रक्टर को भी कॉल नहीं किया जाता है।

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

क्या यह सुनिश्चित करने के लिए कि डेटा प्रकार संरचना के लिए व्यवहार्य है, डेटा के प्रकार (वर्तमान में एक साधारण टाइपपीफ int टी जब तक मैं सब कुछ templatize) परीक्षण करने के लिए कभी भी आवश्यक होगा?

प्रकार संकलन समय पर चेक किए जाते हैं। आप वास्तव में रनटाइम पर उनके बारे में कुछ भी नहीं कर सकते हैं, न ही आपको यथार्थवादी रूप से आवश्यकता होगी। (आपको लगता है कि सभी प्रकार के-जाँच नहीं चाहते हैं, तो क्यों आप एक भाषा है कि आप विशेष रूप से typenames में टाइप करने की हर जगह बलों? :) का उपयोग कर रहे)

6

मैं सच में यकीन है कि जब नहीं कर रहा हूँ वास्तव में मैं बनाम गति

तुम हमेशा अपवाद सुरक्षा के लिए प्रयास करना चाहिए अपवाद सुरक्षा के लिए प्रयास करना चाहिए। ध्यान दें कि "अपवाद सुरक्षा" का अर्थ यह नहीं है, "कुछ गलत होने पर अपवाद फेंकना"। इसका मतलब है "तीन अपवाद गारंटीओं में से एक प्रदान करना: कमजोर, मजबूत या नोट्रो"। अपवाद फेंकना वैकल्पिक है। आपके कोड के कॉलर्स को संतुष्ट होने की अनुमति देने के लिए अपवाद सुरक्षा आवश्यक है कि त्रुटि होने पर उनका कोड सही ढंग से कार्य कर सके।

आप अपवादों के संबंध में विभिन्न सी ++ प्रोग्रामर/टीमों से बहुत अलग शैलियों को देखेंगे। कुछ लोग उन्हें बहुत अधिक उपयोग करते हैं, दूसरों को शायद ही कभी (या यहां तक ​​कि सख्ती से भी नहीं, हालांकि मुझे लगता है कि यह काफी दुर्लभ है। 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)?

आप शायद अपनी संरचना लिख ​​सकते हैं जैसे टी की सभी आवश्यक है कि यह प्रति-रचनात्मक और असाइन करने योग्य है। इसके लिए विशेष परीक्षण जोड़ने की कोई आवश्यकता नहीं है - अगर कोई आपके टेम्पलेट को उस प्रकार के साथ चालू करने का प्रयास करता है जो आपके द्वारा किए गए संचालन का समर्थन नहीं करता है, तो उन्हें संकलन त्रुटि मिल जाएगी। हालांकि, आपको आवश्यकताओं को दस्तावेज करना चाहिए।

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