कुछ भाषाओं के लिए (यानी C ++) रिसोर्स लीक एक कारण नहीं होना चाहिए
C ++ RAII पर आधारित है।
यदि आपके पास ऐसा कोड है जो विफल हो सकता है, वापस आ सकता है या फेंक सकता है (जो कि सबसे सामान्य कोड है), तो आपके पास अपना पॉइंटर एक स्मार्ट पॉइंटर के अंदर लिपटा होना चाहिए (यह मानते हुए कि आपके पास स्टैक पर बनाई गई वस्तु नहीं होने का एक बहुत अच्छा कारण है)।
रिटर्न कोड अधिक क्रिया हैं
वे क्रियात्मक हैं, और कुछ इस तरह विकसित होते हैं:
if(doSomething())
{
if(doSomethingElse())
{
if(doSomethingElseAgain())
{
// etc.
}
else
{
// react to failure of doSomethingElseAgain
}
}
else
{
// react to failure of doSomethingElse
}
}
else
{
// react to failure of doSomething
}
अंत में, आप कोड पहचान किए गए निर्देशों का एक संग्रह है (मैंने उत्पादन कोड में इस तरह का कोड देखा था)।
इस कोड का अच्छी तरह से अनुवाद किया जा सकता है:
try
{
doSomething() ;
doSomethingElse() ;
doSomethingElseAgain() ;
}
catch(const SomethingException & e)
{
// react to failure of doSomething
}
catch(const SomethingElseException & e)
{
// react to failure of doSomethingElse
}
catch(const SomethingElseAgainException & e)
{
// react to failure of doSomethingElseAgain
}
जो सफाई से कोड और एरर प्रोसेसिंग को अलग करता है, जो एक अच्छी बात हो सकती है।
रिटर्न कोड अधिक भंगुर होते हैं
यदि एक संकलक से कुछ अस्पष्ट चेतावनी नहीं मिलती है ("phjr" टिप्पणी देखें), तो उन्हें आसानी से अनदेखा किया जा सकता है।
उपरोक्त उदाहरणों के साथ, किसी की तुलना में मान लें कि वह अपनी संभावित त्रुटि को भूल जाता है (ऐसा होता है ...)। "वापस" आने पर त्रुटि को नजरअंदाज किया जाता है, और संभवतः बाद में विस्फोट होगा (यानी एक पूर्ण सूचक)। एक ही समस्या अपवाद के साथ नहीं होगी।
त्रुटि को नजरअंदाज नहीं किया जाएगा। कभी-कभी, आप चाहते हैं कि यह विस्फोट न हो, हालांकि ... इसलिए आपको सावधानी से चुना जाना चाहिए।
रिटर्न कोड का कभी-कभी अनुवाद किया जाना चाहिए
मान लें कि हमारे पास निम्नलिखित कार्य हैं:
- doSomething, जो NOT_FOUND_ERROR नामक int लौटा सकता है
- doSomethingElse, जो एक बूल को "गलत" (असफल होने पर) लौटा सकता है
- doSomethingElseAgain, जो एक त्रुटि ऑब्जेक्ट (__LINE__, __FILE__ और आधा स्टैक चर के साथ) वापस कर सकता है।
- doTryToDoSomethingWithAllThisMess जो, अच्छी तरह से ... उपरोक्त कार्यों का उपयोग करें, और प्रकार का एक त्रुटि कोड लौटाएं ...
DoTryToDoSomethingWithAllThisMess की वापसी का प्रकार क्या है यदि इसके किसी भी कार्य में विफल रहता है?
रिटर्न कोड एक सार्वभौमिक समाधान नहीं हैं
ऑपरेटर एक त्रुटि कोड वापस नहीं कर सकते। C ++ कंस्ट्रक्टर भी नहीं कर सकते हैं।
रिटर्न कोड का मतलब है कि आप श्रृंखला अभिव्यक्ति नहीं कर सकते
उपरोक्त बिंदु का कोरोलरी। अगर मुझे लिखना है तो क्या होगा:
CMyType o = add(a, multiply(b, c)) ;
मैं नहीं कर सकता, क्योंकि वापसी मूल्य पहले से ही उपयोग किया जाता है (और कभी-कभी, इसे बदला नहीं जा सकता है)। तो रिटर्न वैल्यू पहला पैरामीटर बन जाता है, जिसे संदर्भ के रूप में भेजा जाता है ... या नहीं।
अपवाद टाइप किए गए हैं
आप प्रत्येक प्रकार के अपवाद के लिए अलग-अलग कक्षाएं भेज सकते हैं। स्रोतों के अपवाद (अर्थात स्मृति से बाहर) प्रकाश होना चाहिए, लेकिन कुछ और जितना आवश्यक हो उतना भारी हो सकता है (मुझे जावा एक्ससेप्शन मुझे पूरी तरह से देना पसंद है)।
प्रत्येक कैच को तब स्पेशलाइज किया जा सकता है।
फिर से फेंकने के बिना कभी भी पकड़ (...) का उपयोग न करें
आमतौर पर, आपको एक त्रुटि नहीं छिपानी चाहिए। यदि आप पुन: नहीं फेंकते हैं, तो बहुत कम से कम, फ़ाइल में त्रुटि लॉग करें, संदेश बॉक्स खोलें, जो भी ...
अपवाद हैं ... NUKE
अपवाद के साथ समस्या यह है कि उन्हें अधिक उपयोग करने से कोशिश / कैच से भरा कोड उत्पन्न होगा। लेकिन समस्या कहीं और है: कौन एसटीएल कंटेनर का उपयोग करके अपना कोड पकड़ता है? फिर भी, वे कंटेनर एक अपवाद भेज सकते हैं।
बेशक, सी ++ में, कभी भी एक अपवाद को एक विध्वंसक से बाहर निकलने न दें।
अपवाद हैं ... तुल्यकालिक
अपने धागे को उसके घुटनों पर लाने से पहले, या अपने विंडोज संदेश लूप के अंदर प्रचार करने से पहले उन्हें पकड़ना सुनिश्चित करें।
समाधान उन्हें मिश्रण हो सकता है?
इसलिए मुझे लगता है कि समाधान को फेंकना है जब कुछ नहीं होना चाहिए । और जब कुछ हो सकता है, तो उपयोगकर्ता को उस पर प्रतिक्रिया करने के लिए सक्षम करने के लिए एक रिटर्न कोड या एक पैरामीटर का उपयोग करें।
तो, एकमात्र सवाल "ऐसा क्या है जो नहीं होना चाहिए?"
यह आपके फ़ंक्शन के अनुबंध पर निर्भर करता है। यदि फ़ंक्शन पॉइंटर को स्वीकार करता है, लेकिन निर्दिष्ट करता है कि पॉइंटर नॉन-NULL होना चाहिए, तो उपयोगकर्ता द्वारा NULL पॉइंटर (प्रश्न C C + में होने पर, जब फ़ंक्शन लेखक ने संदर्भों का उपयोग नहीं किया, तो अपवाद को फेंकना ठीक है। संकेत के, लेकिन ...)
एक और समाधान त्रुटि दिखाने के लिए होगा
कभी-कभी, आपकी समस्या यह है कि आप त्रुटियां नहीं चाहते हैं। अपवाद या त्रुटि वापसी कोड का उपयोग करना अच्छा है, लेकिन ... आप इसके बारे में जानना चाहते हैं।
मेरी नौकरी में, हम एक तरह के "Assert" का उपयोग करते हैं। यह कॉन्फ़िगरेशन फ़ाइल के मूल्यों पर निर्भर करता है, कोई बात नहीं डिबग / रिलीज संकलन विकल्प:
- त्रुटि लॉग करें
- "अरे, आपको कोई समस्या है" के साथ एक संदेश बॉक्स खोलें
- "अरे, आपको कोई समस्या है, क्या आप डीबग करना चाहते हैं" के साथ एक संदेश बॉक्स खोलें
विकास और परीक्षण दोनों में, यह उपयोगकर्ता को समस्या का ठीक-ठीक पता लगाने में सक्षम करता है जब इसका पता लगाया जाता है, और उसके बाद नहीं (जब कुछ कोड रिटर्न वैल्यू की परवाह करता है, या एक कैच के अंदर)।
विरासत कोड को जोड़ना आसान है। उदाहरण के लिए:
void doSomething(CMyObject * p, int iRandomData)
{
// etc.
}
एक समान कोड की ओर जाता है:
void doSomething(CMyObject * p, int iRandomData)
{
if(iRandomData < 32)
{
MY_RAISE_ERROR("Hey, iRandomData " << iRandomData << " is lesser than 32. Aborting processing") ;
return ;
}
if(p == NULL)
{
MY_RAISE_ERROR("Hey, p is NULL !\niRandomData is equal to " << iRandomData << ". Will throw.") ;
throw std::some_exception() ;
}
if(! p.is Ok())
{
MY_RAISE_ERROR("Hey, p is NOT Ok!\np is equal to " << p->toString() << ". Will try to continue anyway") ;
}
// etc.
}
(मेरे पास समान मैक्रोज़ हैं जो केवल डीबग पर सक्रिय हैं)।
ध्यान दें कि उत्पादन पर, कॉन्फ़िगरेशन फ़ाइल मौजूद नहीं है, इसलिए क्लाइंट इस मैक्रो का परिणाम कभी नहीं देखता है ... लेकिन जरूरत पड़ने पर इसे सक्रिय करना आसान है।
निष्कर्ष
जब आप रिटर्न कोड का उपयोग करके कोड बनाते हैं, तो आप अपने आप को असफलता के लिए तैयार कर रहे हैं, और आशा है कि आपके परीक्षण के किले पर्याप्त सुरक्षित हैं।
जब आप अपवाद का उपयोग करके कोड बनाते हैं, तो आप जानते हैं कि आपका कोड विफल हो सकता है, और आमतौर पर आपके कोड में चुने हुए रणनीतिक स्थिति पर काउंटरफायर कैच डाल सकता है। लेकिन आमतौर पर, आपका कोड "यह क्या करना चाहिए" के बारे में अधिक है "फिर मुझे डर है कि क्या होगा"।
लेकिन जब आप बिल्कुल भी कोड करते हैं, तो आपको अपने निपटान में सबसे अच्छा उपकरण का उपयोग करना चाहिए, और कभी-कभी, यह "कभी भी एक त्रुटि छिपाएं, और जितनी जल्दी हो सके इसे दिखाएं"। इस मैक्रो के ऊपर मैंने इस दर्शन का अनुसरण किया।