2008-09-07 14 views
31

मैं this article कई साल पहले आंद्रेई Alexandrescu और Petru Marginean ने लिखा है, जो प्रस्तुत करता है और अपवाद-सुरक्षित कोड लिखने के लिए ScopeGuard नामक एक उपयोगिता वर्ग की चर्चा में आए। मैं जानना चाहता हूं कि इन वस्तुओं के साथ कोडिंग वास्तव में बेहतर कोड की ओर ले जाती है या यदि यह त्रुटि प्रबंधन को रोक देती है, तो शायद गार्ड के कॉलबैक को कैच ब्लॉक में बेहतर तरीके से प्रस्तुत किया जाएगा? क्या किसी को वास्तविक उत्पादन कोड में इनका उपयोग करने का कोई अनुभव है?क्या स्कोपगार्ड का उपयोग वास्तव में बेहतर कोड का कारण बनता है?

+1

C++ 0x/C++ 11 करता है कि अब "shared_ptr" के साथ:

यह सी में इतना महत्वपूर्ण ++ कि डी में इसके लिए भी एक विशेष वाक्य रचना थी। –

+0

मुझे लगता है कि यह आपको अधिक शक्ति दे रहा है। डेटाबेस के साथ उदाहरण बहुत अच्छा है। Shared_ptr का उपयोग करके यह केवल विनाशक को कॉल करेगा जो आमतौर पर स्कोप्डगार्ड का उपयोग करते समय कनेक्शन को बंद कर देता है, आप वास्तव में अपवाद के मामले में रोलबैक कर सकते हैं ... –

उत्तर

59

यह निश्चित रूप से अपने कोड में सुधार। आपका तात्कालिक रूप से तैयार दावा, कि यह अस्पष्ट है और catch ब्लॉक से उस कोड की योग्यता सी ++ में सच नहीं है क्योंकि आरएआईआई एक स्थापित मुहावरे है। C++ संसाधन से निपटने संसाधन अधिग्रहण द्वारा किया जाता है और कचरा संग्रहण निहित नाशक कॉल द्वारा किया जाता है।

दूसरी ओर, स्पष्ट catch ब्लॉक कोड को फहराएंगे और सूक्ष्म त्रुटियों को पेश करेंगे क्योंकि कोड प्रवाह अधिक जटिल हो जाता है और संसाधन प्रबंधन को स्पष्ट रूप से किया जाना चाहिए। (ScopeGuard रों सहित)

आरए II सी में एक अस्पष्ट तकनीक नहीं है ++ लेकिन मजबूती से सबसे अच्छा अभ्यास की स्थापना की।

+6

+1 आधुनिक सी ++ तकनीकों के लिए चिपकने के लिए। यह भी ध्यान दिया जाना चाहिए कि अलेक्जेंड्रेस्कू ने स्कोपगार्ड का एक नया संस्करण यहां प्रस्तुत किया: http://channel9.msdn.com/Shows/Going+Deep/C-and-Beyond-2012-Andrei-Alexandrescu- सिस्टम-एरर- हैंडलिंग-in -सी जो उपयोग करने के लिए बहुत आसान है। माइक एक संपादन के लायक हो। – odinthenerd

1

मैं इस विशेष टेम्पलेट का उपयोग नहीं किया है, लेकिन मैं कुछ इसी तरह का उपयोग किया है पहले। हां, यह विभिन्न तरीकों से लागू समान रूप से मजबूत कोड की तुलना में स्पष्ट कोड का कारण बनता है।

2

मैं अक्सर स्मृति उपयोग, चीजों को मुक्त कर दिया जा सकता है कि ओएस से लौट रहे थे कि जरूरत की रखवाली के लिए इसका इस्तेमाल करते हैं। उदाहरण के लिए:

DATA_BLOB blobIn, blobOut; 
blobIn.pbData=const_cast<BYTE*>(data); 
blobIn.cbData=length; 

CryptUnprotectData(&blobIn, NULL, NULL, NULL, NULL, CRYPTPROTECT_UI_FORBIDDEN, &blobOut); 
Guard guardBlob=guardFn(::LocalFree, blobOut.pbData); 
// do stuff with blobOut.pbData 
28

हां।

यदि सी ++ कोड का एक टुकड़ा है तो मैं प्रत्येक सी ++ प्रोग्रामर को 10 मिनट सीखने की सलाह दे सकता हूं, यह स्कोपगार्ड (अब स्वतंत्र रूप से उपलब्ध Loki library का हिस्सा है)।

मैंने स्कोपगार्ड के एक छोटे से विन 32 जीयूआई प्रोग्राम के लिए एक (थोड़ा संशोधित) संस्करण का उपयोग करने का प्रयास करने का निर्णय लिया, जिस पर मैं काम कर रहा था। Win32 जैसा कि आप जानते हैं कि कई अलग-अलग प्रकार के संसाधन हैं जिन्हें विभिन्न तरीकों से बंद करने की आवश्यकता है (उदाहरण के लिए कर्नेल हैंडल आमतौर पर CloseHandle() के साथ बंद होते हैं, जीडीआई BeginPaint() को EndPaint() आदि के साथ जोड़ा जाना आवश्यक है) मैंने इन सभी संसाधनों के साथ स्कोपगार्ड का उपयोग किया, और new के साथ काम कर रहे बफर आवंटित करने के लिए (उदाहरण के लिए यूनिकोड से/चरित्र सेट रूपांतरणों के लिए)।

क्या मुझे चकित कितना कम कार्यक्रम था। असल में, यह एक जीत-जीत है: आपका कोड एक ही समय में छोटा और अधिक मजबूत हो जाता है। भविष्य कोड कुछ भी रिसाव नहीं कर सकता है। वे बस नहीं कर सकते हैं। कितना मजेदार था वो?

+0

डाउनवॉटर: टिप्पणी करने की देखभाल? –

-2

मैं कहना है, नहीं, नहीं ऐसा नहीं होता है। यहां दिए गए उत्तरों यह दिखाने में मदद करते हैं कि यह वास्तव में एक भयानक विचार क्यों है। पुन: प्रयोज्य कक्षाओं के माध्यम से संसाधन हैंडलिंग किया जाना चाहिए। एक स्कोप गार्ड का उपयोग करके हासिल की गई एकमात्र चीज वेज़ू को डीआरवाई का उल्लंघन करना है और संसाधन को संभालने के लिए एक वर्ग लिखने के बजाय अपने संसाधन कोडिंग कोड को डुप्लिकेट करना है और फिर यह पूरी तरह से है।

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

1

मुझे लगता है कि उत्तर के ऊपर एक महत्वपूर्ण नोट की कमी है। जैसा कि अन्य ने इंगित किया है, आप असफलता (अपवाद) से स्वतंत्र आवंटित संसाधनों को मुक्त करने के लिए ScopeGuard का उपयोग कर सकते हैं। लेकिन यह एकमात्र चीज नहीं हो सकती है जिसके लिए आप स्कोप गार्ड का उपयोग करना चाहेंगे। वास्तव में, एक अलग उद्देश्य के लिए लिंक किए गए आलेख में उदाहरण ScopeGuard का उपयोग करते हैं: ट्रांसकेशन। संक्षेप में, यह उपयोगी हो सकता है यदि आपके पास एकाधिक ऑब्जेक्ट हैं (भले ही वे ऑब्जेक्ट्स RAII का सही तरीके से उपयोग करें) कि आपको किसी ऐसे राज्य में रखने की आवश्यकता है जो किसी भी तरह से संबंधित है। यदि उन वस्तुओं में से किसी भी स्थिति की स्थिति में अपवाद होता है (जो, मुझे लगता है, आमतौर पर इसका मतलब है कि इसका राज्य नहीं बदला है) तो पहले से लागू सभी परिवर्तनों को वापस रोल करने की आवश्यकता है। यह समस्या का अपना सेट बनाता है (क्या होगा यदि रोलबैक भी विफल हो जाए?)। आप अपनी खुद की कक्षा को रोल करने का प्रयास कर सकते हैं जो इस तरह के सहसंबंधित वस्तुओं का प्रबंधन करता है, लेकिन उन लोगों की संख्या बढ़ने के कारण यह गन्दा हो जाएगा और आप शायद ScopeGuard आंतरिक रूप से किसी भी तरह से उपयोग करने के लिए वापस आ जाएंगे।

1

हां।

void somefunction() { 
    writeln("function enter"); 
    // c++ has similar constructs but not in syntax level 
    scope(exit) writeln("function exit"); 

    // do what ever you do, you never miss the function exit output 
} 
संबंधित मुद्दे