2012-07-13 10 views
7

सी ++ में वैज्ञानिक सॉफ्टवेयर कोडिंग के कई वर्षों के बाद सुनिश्चित नहीं हैं, मैं अभी भी नहीं अपवाद के लिए इस्तेमाल किया पाने के लिए लग सकता है और मुझे पता नहीं है जब मैं उन्हें इस्तेमाल करना चाहिए। मुझे पता है कि उन्हें कार्यक्रम प्रवाह को नियंत्रित करने के लिए उपयोग कर एक बड़ा (एक वर्ग है कि एक छवि मुखौटा का प्रतिनिधित्व करता है और उपयोगकर्ता बहुभुज के रूप में यह करने के लिए क्षेत्रों को जोड़ने की सुविधा देता है से अंश) उदाहरण का अनुसरण नहीं-नहीं, लेकिन अन्यथा की तुलना में है कि ... पर विचार करें:जब C++ में अपवाद का उपयोग करने के

class ImageMask 
{ 
public: 
    ImageMask() {} 
    ImageMask(const Size2DI &imgSize); 

    void addPolygon(const PolygonI &polygon); 

protected: 
    Size2DI imgSize_; 
    std::vector<PolygonI> polygons_; 
}; 

इस कक्षा के लिए डिफ़ॉल्ट कन्स्ट्रक्टर एक अपरिभाषित छवि आकार के साथ एक बेकार उदाहरण बनाता है। मैं नहीं चाहता कि उपयोगकर्ता ऐसी ऑब्जेक्ट में बहुभुज जोड़ने में सक्षम हो। लेकिन मुझे यकीन नहीं है कि उस स्थिति को कैसे संभालना है। जब आकार अपरिभाषित है, और addPolygon() कहा जाता है, क्या मुझे:

  1. चुपचाप वापसी,
  2. ज़ोर (imgSize_.valid) इस वर्ग का उपयोग कर कोड में उल्लंघन का पता लगाने और एक रिलीज होने से पहले उन्हें ठीक करने के,
  3. एक अपवाद फेंक दिया?

अधिकांश समय मैं 1 या 2 के साथ जाता हूं) (मेरे मनोदशा के आधार पर), क्योंकि ऐसा लगता है कि अपवाद महंगा, गन्दा और बस इतना आसान परिदृश्य के लिए अधिक है। कृपया कुछ अंतर्दृष्टि कृपया?

+4

डिफ़ॉल्ट निर्माण को रोकें? अमान्य 'छविमास्क' उदाहरण बनाए जा रहे हैं। – hmjd

+1

आपको डिफ़ॉल्ट कन्स्ट्रक्टर की आवश्यकता क्यों है? –

+0

एक डिफ़ॉल्ट कन्स्ट्रक्टर उपयोगी हो सकता है ताकि आप उस प्रकार की ऑब्जेक्ट्स को कुछ कंटेनरों में रख सकें। – MadScientist

उत्तर

6

सामान्य नियम है कि आप एक अपवाद फेंक जब आप इच्छित कार्य पूरा नहीं किया जा सकता है। तो आपके मामले में, हाँ, जब addPolygon कहा जाता है और आकार अपरिभाषित या असंगत होता है तो अपवाद फेंकने का अर्थ होता है।

चुपचाप लौट लगभग हमेशा क्या करना गलत बात है। assert एक अच्छी त्रुटि-हैंडलिंग तकनीक नहीं है (यह एक डिजाइन/दस्तावेज़ीकरण तकनीक से अधिक है)।

हालांकि, आपके मामले में इंटरफ़ेस का एक नया स्वरूप एक त्रुटि हालत असंभव बनाने के लिए या संभावना नहीं बेहतर हो सकता है। उदाहरण के लिए, कुछ इस तरह:

class ImageMask 
{ 
public: 
    // Constructor requires collection of polygons and size. 
    // Neither can be changed after construction. 
    ImageMask(std::vector<PolygonI>& polygons, size_t size); 
} 

या इस

class ImageMask 
{ 
public: 
    class Builder 
    { 
    public: 
     Builder(); 
     void addPolygon(); 
    }; 

    ImageMask(const Builder& builder); 
} 

// used like this 
ImageMask::Builder builder; 
builder.addPolygon(polyA); 
builder.addPolygon(polyB); 
ImageMask mask(builder); 
1

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

नोट आप अधिक विकल्प हैं कि:

  • अपने स्वयं के ज़ोर कि हमेशा कॉल std :: समाप्त करता है और अतिरिक्त लॉगिंग
  • (के रूप में दूसरों पहले ही बताया) डिफ़ॉल्ट निर्माता अक्षम आविष्कार - यह मेरी पसंदीदा
2

मैं किसी भी स्थिति है जहाँ यह डेटा बेकार राज्य के कुछ प्रकार में है कि बनाने के लिए संभव है से बचने के लिए कोशिश करेंगे। यदि आपको एक बहुभुज की आवश्यकता है जो खाली नहीं है, तो खाली बहुभुजों को न जाने दें और आप स्वयं को बहुत परेशानी बचाएं क्योंकि संकलक लागू करेगा कि कोई खाली बहुभुज नहीं है।

मैं कभी भी चुप रिटर्न का उपयोग नहीं करता, क्योंकि वे बग छुपाते हैं और इससे बग को और अधिक जटिल बनाना पड़ता है।

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

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

तरह का संबंध टॉरस्टेन

1
  1. "चुपचाप लौट" - कि असली 'बड़ा नहीं-नहीं' है। कार्यक्रम को पता होना चाहिए कि क्या गलत है।
  2. "जोर दें" - दूसरा नियम यह है कि केवल सामान्य प्रोग्राम के प्रवाह को पुनर्स्थापित नहीं किया जा सकता है।
  3. "फेंक अपवाद" - हाँ, यह सही और अच्छी तकनीक है। बस अपवाद-सुरक्षा के बारे में परवाह करें। GotW पर अपवाद-सुरक्षित कोडिंग के बारे में कई लेख हैं।

अपवादों को डरो मत। वे काटने नहीं करते हैं। :) यदि आप इस तकनीक को पर्याप्त ले लेंगे, तो आप एक मजबूत कोडर बनेंगे। ;)

+0

मजेदार है कि जावा के तहत अपवाद बहुत आसान और सामान्य हैं, जबकि सी ++ के साथ वे – marcinj

+0

आश्चर्यचकित नहीं हैं। जावा अपनी याददाश्त स्वयं ही प्रबंधित करता है; सीपीपी-डेवलपर (और सौभाग्य से या दुर्भाग्य से - जरूरी) अपने दिमाग से अपनी याददाश्त का प्रबंधन कर सकता है। ;) –

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