2015-10-23 8 views
6

यदि कोई ऑब्जेक्ट किसी ऑब्जेक्ट के निर्माण में अधिग्रहण करने की आवश्यकता है तो असफल हो सकता है, यदि स्थानीय कोडिंग मानक द्वारा अपवादों को निषिद्ध किया जाता है तो क्या आरएआईआई करना संभव है?क्या बिना अपवाद के आरएआईआई करना संभव है?

यदि हां, तो इस मामले में संसाधन अधिग्रहण की विफलता को संभालने के लिए कैननिक तरीके क्या है?

+1

जब मैं किसी भी कारण से अपवादों का उपयोग नहीं कर सकता, तो मैं उन वस्तुओं के लिए प्रारंभिक तरीकों को बनाने का अंत करता हूं जो निर्माण में विफल हो सकते हैं। तो कन्स्ट्रक्टर छोटे सेटअप के अलावा कुछ भी नहीं करेगा। तब मेरे पास एक इनिट विधि हो सकती है जो वास्तविक संसाधन अधिग्रहण करता है और तदनुसार सत्य/गलत लौटाता है। –

+2

क्या आपके दिशानिर्देश इस तरह की स्थितियों के बारे में कुछ नहीं कहते हैं? यह * सब के बाद एक बहुत आम सी ++ मुहावरे है। और यदि दिशानिर्देश इसकी अनुमति देते हैं, तो आप हमेशा [मानक I/O लाइब्रेरी] (http://en.cppreference.com/w/cpp/io) और इसकी स्ट्रीम जैसे सिस्टम का उपयोग कर सकते हैं, उदा। कि त्रुटियों की जांच करने के लिए धाराओं का उपयोग किया जा सकता है, या 'is_open' फ़ंक्शन वाले फ़ाइल स्ट्रीम की तरह। –

+0

@ जोचिमपिलबोर्ग मुझे नहीं लगता कि इसे दिशानिर्देशों में माना गया था, उन्हें अपडेट करने की आवश्यकता हो सकती है (हालांकि यह एक एम्बेडेड रीयलटाइम सिस्टम है, और अपवाद पसंद नहीं हैं!) भले ही, मेरी भावना यह है कि यह संभव नहीं है, इसलिए बस इस सवाल के लिए मैं अपनी भावना की पुष्टि करना चाहता हूं! :-) – Joe

उत्तर

6

मैं सामान्य रूप से अमान्य वस्तु दृष्टिकोण के साथ नहीं जाऊंगा क्योंकि मैं इसे खराब डिजाइन के रूप में मानता हूं। निर्माण के बाद, वस्तु एक ऐसे राज्य में होनी चाहिए जहां आविष्कार स्थापित किए जाएं (यही एकमात्र उद्देश्य है जिसे एक निर्माता को सेवा देना चाहिए)। पर std::vector जैसे कुछ को लागू करने पर विचार करें, लेकिन strange_vector<int>(10, 0) पर कॉल करने के बाद, ऑब्जेक्ट एक अनुपयोगी स्थिति में होगा क्योंकि आवंटन विफल रहा।

इसके बजाय मैं कंस्ट्रक्टर्स निजी घोषित करने और एक कारखाने तरीका है जिसके रिटर्न का प्रयोग करेंगे एक वैकल्पिक:

class file 
{ 
public: 
    ~file() {fclose(m_file);} 

    static std::optional<file> open(std::string const& filename) 
    { 
     auto f = fopen(filename.c_str(), "r"); 
     if (f) 
     { 
      return std::make_optional<file>(f); 
     } 
     else 
     { 
      return std::nullopt; 
     } 
    } 

private: 
    file(FILE* file); 
    FILE* m_file; 
}; 

अपवाद संचालन की सबसे बड़ी लाभों में से एक है (त्रुटि हैंडलिंग और सामान्य कोड पथ decoupling के अलावा) है कि आप नहीं कर सकते हैं उन्हें गलती से अनदेखा करें। यदि आप इसे चाहते हैं, तो आप अपनी खुद की कक्षा optional के समान बना सकते हैं, जब वैध ऑब्जेक्ट के साथ प्रारंभ नहीं किया गया है, तो एक त्रुटि संदेश लॉग करता है और आपके प्रोग्राम को समाप्त करता है (या कोई अन्य उचित त्रुटि प्रबंधन)। मुझे लगता है कि talk from A. Alexandrescu about systematic error handling है जहां वह कक्षा Expected<T> लागू करता है जिसमें T या अपवाद का मान शामिल है। आप इसका आधार उपयोग कर सकते हैं और अपवाद के बजाय वहां आपकी त्रुटि को संभालने में जोड़ें।

std::optional अभी तक मानक का हिस्सा नहीं है, लेकिन आप हाल ही में कंपाइलर्स, बूस्ट में, या अन्य पुस्तकालयों के हिस्से के रूप में आसानी से कार्यान्वयन प्राप्त कर सकते हैं।

+0

आपने स्थानीय 'f' और सदस्य 'm_file' को मिश्रित किया, है ना? –

+0

@ MatthäusBrandl हाँ, इसे स्पॉट करने के लिए धन्यवाद। – Jens

1

आप हमेशा bool valid(void) विधि बना सकते हैं। कन्स्ट्रक्टर तब अप्रिय स्थिति निर्धारित कर सकता है और आपके कोड में, आप इस काम के बाद गीले निर्माण के बाद जांच सकते हैं या नहीं।

class foo 
{ 
public: 
    foo(const char *Filename) 
    { 
     mValid = false; 

     if(fopen(Filename) == NULL) 
      return; 

     mValid = true; 
    } 

    bool valid(void) { return mValid; } 

    private: 
     bool mValid; 
}; 

void myfunc(void) 
{ 
    foo fl("myfile"); 
    if(!fl.valid()) 
    { 
     printf("Error\n"); 
     return; 
    } 
} 
+0

मुझे वास्तव में इस दृष्टिकोण को पसंद नहीं है। क्या होगा यदि मैं फ़ाइल का उपयोग करने वाली foo की विधि कहूं, लेकिन प्रारंभिकता विफल हो गई है? रचनाकार जो ऑब्जेक्ट के इनवेरिएंट को स्थापित नहीं करते हैं, वे बिना किसी चलते हैं। – Jens

+0

यदि आप एक विधि को कॉल करते हैं जो foo का उपयोग करता है तो उसे आंतरिक रूप से मान्य करना चाहिए कि फ़ाइल वास्तव में मान्य है। खैर, यह बदसूरत है, लेकिन कम से कम यह गारंटी देता है कि ऑब्जेक्ट स्वयं सही काम करता है। – Devolus

+0

जो प्रत्येक विधि कॉल के लिए जांच जोड़ता है। मुझे यकीन नहीं है कि ओपी इसे अपने एम्बेडेड डोमेन में चाहता है, और मुझे नहीं लगता कि मैं इसे सामान्य रूप से चाहता हूं, उदा। जब इस दृष्टिकोण के साथ एक वेक्टर वर्ग जो प्रत्येक पहुंच के लिए जांच करता है ... – Jens

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