C ++ में कोई 'अंततः' निर्माण क्यों नहीं है?


57

C ++ में एक्सेप्शन हैंडलिंग केवल कोशिश / फेंक / पकड़ने तक सीमित है। ऑब्जेक्ट पास्कल, जावा, सी # और पायथन के विपरीत, यहां तक ​​कि सी ++ 11 में, finallyनिर्माण को लागू नहीं किया गया है।

मैंने C ++ साहित्य का एक बहुत बड़ा भाग देखा है, जो "अपवाद सुरक्षित कोड" पर चर्चा करता है। Lippman लिखते हैं कि अपवाद सुरक्षित कोड एक महत्वपूर्ण लेकिन उन्नत, कठिन विषय है, जो उनके प्राइमर के दायरे से परे है - जो कि लगता है कि सुरक्षित कोड C ++ के लिए मौलिक नहीं है। हर्ब सटर अपने असाधारण C ++ में विषय के लिए 10 अध्याय समर्पित करता है!

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

C ++ 11 में लागू सभी 'घंटियाँ और सीटी' को ध्यान में रखते हुए, मुझे यह जानकर आश्चर्य हुआ कि 'आखिर' अभी भी नहीं था।

तो, finallyC ++ में निर्माण को कभी लागू क्यों नहीं किया गया? यह वास्तव में बहुत मुश्किल या उन्नत अवधारणा नहीं है कि प्रोग्रामर को 'अपवाद सुरक्षित कोड' लिखने में मदद करने की दिशा में लंबा रास्ता तय किया जाए।


25
आखिर क्यों नहीं? क्योंकि आप विध्वंसक में उन चीजों को छोड़ते हैं जो ऑब्जेक्ट (या स्मार्ट पॉइंटर) के दायरे से बाहर निकलते ही अपने आप आग लग जाती हैं। विनाशकारी अंततः {} से बेहतर होते हैं क्योंकि यह वर्कफ़्लो को क्लीनअप लॉजिक से अलग करता है। जिस तरह आप फ्री में कॉल नहीं करना चाहेंगे () एक कचरा एकत्र भाषा में अपने वर्कफ़्लो को अव्यवस्थित करना।
माइक 30


8
सवाल पूछते हुए, " finallyसी ++ में कोई क्यों नहीं है, और इसके स्थान पर अपवाद से निपटने के लिए क्या तकनीकों का उपयोग किया जाता है?" इस साइट के लिए मान्य और विषय पर है। मौजूदा जवाब इस अच्छी तरह से कवर करते हैं, मुझे लगता है। "सी ++ डिजाइनरों के finallyसार्थक कारणों को शामिल न करने के कारणों पर चर्चा में इसे बदल रहा है?" और " finallyC ++ में जोड़ा जाना चाहिए?" और इस सवाल पर टिप्पणियों पर चर्चा और हर उत्तर पर ले जाने से इस प्रश्नोत्तर साइट का मॉडल फिट नहीं होता है।
जोश केली

2
यदि आपके पास अंत में है, तो आपके पास पहले से ही चिंताओं का अलगाव है: मुख्य कोड ब्लॉक यहां है, और सफाई की चिंता का यहां ध्यान रखा गया है।
कज़

2
@Kaz। अंतर स्पष्ट बनाम स्पष्ट है। एक विध्वंसक आपको स्वचालित सफाई देता है कि कैसे एक पुराने पुराने आदिम को साफ किया जाता है क्योंकि यह स्टैक से बाहर निकलता है। आपको कोई स्पष्ट सफाई करने की आवश्यकता नहीं है और अपने मुख्य तर्क पर ध्यान केंद्रित कर सकते हैं। कल्पना करें कि यदि आपने कोशिश / अंत में स्टैक आवंटित प्राइमेटिक्स को साफ करना है तो यह कितना जटिल होगा। साफ सफाई बेहतर है। अनाम कार्यों के लिए वर्ग वाक्य रचना की तुलना प्रासंगिक नहीं है। हालांकि एक समारोह के लिए प्रथम श्रेणी के कार्यों को पारित करने से जो एक हैंडल को जारी करता है, मैनुअल क्लीनअप को केंद्रीकृत कर सकता है।
माइक 30

जवाबों:


57

@ Nemanja के उत्तर पर कुछ अतिरिक्त टिप्पणी के रूप में (जो, क्योंकि यह स्ट्रॉस्ट्रुप उद्धृत करता है, वास्तव में एक उत्तर के रूप में अच्छा है जितना आपको मिल सकता है):

यह वास्तव में C ++ के दर्शन और मुहावरों को समझने की बात है। एक ऐसे ऑपरेशन का अपना उदाहरण लें, जो एक निरंतर वर्ग पर एक डेटाबेस कनेक्शन खोलता है और यह सुनिश्चित करना है कि यह अपवाद बंद कर दिया जाता है तो यह कनेक्शन बंद कर देता है। यह अपवाद सुरक्षा का मामला है और अपवादों (C ++, C #, डेल्फी ...) के साथ किसी भी भाषा पर लागू होता है।

try/ का उपयोग करता है कि भाषा में finally, कोड कुछ इस तरह लग सकता है:

database.Open();
try {
    database.DoRiskyOperation();
} finally {
    database.Close();
}

सरल और सीधा। हालाँकि, कुछ नुकसान हैं:

  • यदि भाषा में नियतात्मक विध्वंसक नहीं हैं, तो मुझे हमेशाfinally ब्लॉक लिखना होगा , अन्यथा मैं संसाधनों को लीक करता हूं।
  • यदि DoRiskyOperationएकल विधि कॉल से अधिक है - अगर मुझे tryब्लॉक में करने के लिए कुछ प्रसंस्करण है - तो Closeऑपरेशन समाप्त हो सकता है ऑपरेशन से एक सभ्य बिट दूर Open। मैं अपने अधिग्रहण के बगल में अपना सफाई नहीं लिख सकता।
  • अगर मेरे पास कई संसाधन हैं जिन्हें अधिग्रहित करने की आवश्यकता है, तो अपवाद-सुरक्षित तरीके से मुक्त किया जाए, मैं कई परतों के साथ try/ finallyब्लॉक को समाप्त कर सकता हूं ।

C ++ दृष्टिकोण इस तरह दिखाई देगा:

ScopedDatabaseConnection scoped_connection(database);
database.DoRiskyOperation();

यह पूरी तरह से finallyदृष्टिकोण के सभी नुकसानों को हल करता है । इसके अपने नुकसान के कुछ जोड़े हैं, लेकिन वे अपेक्षाकृत छोटे हैं:

  • एक अच्छा मौका है कि आपको ScopedDatabaseConnectionस्वयं कक्षा लिखने की आवश्यकता है । हालांकि, यह एक बहुत ही सरल कार्यान्वयन है - कोड की केवल 4 या 5 लाइनें।
  • इसमें एक अतिरिक्त स्थानीय वैरिएबल बनाना शामिल है - जिसका आप स्पष्ट रूप से प्रशंसक नहीं हैं, "अपनी गंदगी को साफ करने के लिए अपने विध्वंसक पर भरोसा करने के लिए लगातार कक्षाएं बनाने और नष्ट करने के बारे में आपकी टिप्पणी के आधार पर बहुत खराब है" - लेकिन एक अच्छा संकलक का अनुकूलन करेगा किसी भी अतिरिक्त कार्य में एक अतिरिक्त स्थानीय चर शामिल है। अच्छा C ++ डिजाइन इस प्रकार के अनुकूलन पर बहुत कुछ निर्भर करता है।

निजी तौर पर, इन फायदों और नुकसान को देखते हुए, मैं RAII को एक बहुत बेहतर तकनीक मानता हूं finally। आपकी माइलेज भिन्न हो सकती है।

अंत में, क्योंकि RAII C ++ में इस तरह की एक अच्छी तरह से स्थापित मुहावरा है, और कई Scoped...वर्गों के लेखन के बोझ से कुछ डेवलपर्स को राहत देने के लिए , स्कोपगार्ड और बूस्ट.स्कोपसिट जैसे पुस्तकालय हैं जो इस तरह के निर्धारक सफाई की सुविधा प्रदान करते हैं।


8
C # का usingकथन है, जो IDisposableइंटरफ़ेस को लागू करने वाली किसी भी वस्तु को स्वचालित रूप से साफ़ करता है। तो जबकि यह गलत हो सकता है, इसे प्राप्त करना बहुत आसान है।
रॉबर्ट हार्वे

18
अस्थायी स्टेट चेंज रिवर्सल का ख्याल रखने के लिए एक पूरी तरह से नया वर्ग लिखने के लिए, एक कंपाइलर द्वारा एक try/finallyनिर्माण के साथ लागू किए गए एक डिज़ाइन मुहावर का उपयोग करते हुए, क्योंकि कंपाइलर एक try/finallyनिर्माण को उजागर नहीं करता है और इसे एक्सेस करने का एकमात्र तरीका क्लास-आधारित है मुहावरा, "फायदा नहीं है?" यह एक अमूर्त व्युत्क्रम की बहुत परिभाषा है।
मेसन व्हीलर

15
@MasonWheeler - उम्म, मैंने यह नहीं कहा कि नई क्लास लिखने का एक फायदा है। मैंने कहा यह नुकसान है। संतुलन पर है, हालांकि, मैं आरए II करना पसंद करते हैं होने का उपयोग करने के finally। जैसा मैंने कहा, आपका माइलेज अलग-अलग हो सकता है।
जोश केली

7
@ जोशकेल्ली: 'गुड सी ++ डिजाइन इस प्रकार के अनुकूलन पर बहुत निर्भर करता है।' बाहरी कोड के gobs लेखन और फिर संकलक अनुकूलन पर भरोसा अच्छा डिजाइन है ?! IMO यह अच्छे डिजाइन का विरोध है। अच्छे डिजाइन के मूल सिद्धांतों में संक्षिप्त है, आसानी से पठनीय कोड। डिबग करने के लिए कम, बनाए रखने के लिए कम, आदि आदि। आपको कोड के gobs नहीं लिखना चाहिए और फिर संकलक पर भरोसा करना चाहिए ताकि यह सब दूर हो जाए - IMO जिसका कोई मतलब नहीं है!
वेक्टर

14
@ माइक: इतना सफाई कोड (या तथ्य यह है कि सफाई होना चाहिए) को दोहराते हुए कोड-बेस पर "संक्षिप्त" और "आसानी से पठनीय" है? RAII के साथ, आप एक बार ऐसा कोड लिखते हैं, और यह स्वचालित रूप से हर जगह लागू होता है।
मकारसे

55

से क्यों सी प्रदान ++ नहीं करता है एक "अंत में" का निर्माण? में Bjarne Stroustrup की सी ++ शैली और तकनीक पूछे जाने वाले प्रश्न :

क्योंकि C ++ एक विकल्प का समर्थन करता है जो लगभग हमेशा बेहतर होता है: "संसाधन अधिग्रहण आरंभीकरण है" तकनीक (TC ++ PL3 अनुभाग 14.4)। मूल विचार एक स्थानीय वस्तु द्वारा एक संसाधन का प्रतिनिधित्व करना है, ताकि स्थानीय वस्तु का विनाशकर्ता संसाधन को मुक्त कर दे। इस तरह, प्रोग्रामर संसाधन जारी करना नहीं भूल सकता।


5
लेकिन उस तकनीक के बारे में कुछ भी नहीं है जो सी ++ के लिए विशिष्ट है, क्या वहां है? आप किसी भी भाषा में ऑब्जेक्ट्स, कंस्ट्रक्टर्स और डिस्ट्रक्टर्स के साथ RAII कर सकते हैं। यह एक शानदार तकनीक है, लेकिन RAII केवल मौजूदा का मतलब यह नहीं है कि एक finallyनिर्माण हमेशा और हमेशा के लिए बेकार है, इसके बावजूद स्ट्रासअप क्या कह रहा है। महज यह तथ्य कि C ++ में "अपवाद सुरक्षित कोड" लिखना एक बड़ी बात है, इसका प्रमाण है। हेक, सी # में दोनों विध्वंसक हैं और finally, और वे दोनों उपयोग करते हैं।
टैक्रॉय

28
@ टैकरॉय: सी ++ उन कुछ मुख्यधारा की भाषाओं में से एक है जिनमें नियतात्मक विध्वंसक हैं। इस उद्देश्य के लिए C # "विध्वंसक" बेकार हैं, और आपको RAII के लिए "ब्लॉक" का उपयोग करके मैन्युअल रूप से लिखना होगा।
नेमेनजा ट्रिफ़ुनोविक

15
@ मायके आपके पास "अंत में C ++ एक" अंततः "निर्माण क्यों प्रदान नहीं करता है?" सीधे स्ट्रॉस्ट्रुप से खुद वहां पहुंचे। आपके द्वारा और अधिक क्या पूछा जा सकता है? यही कारण है कि

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

19
@ काज: मुझे केवल एक बार विध्वंसक में सफाई करने के लिए याद रखने की आवश्यकता है, और तब से मैं सिर्फ ऑब्जेक्ट का उपयोग करता हूं। मुझे हर बार ब्लॉक को आवंटित करने वाले ऑपरेशन का उपयोग करने के लिए अंत में सफाई करने के लिए याद रखने की आवश्यकता है।
डेवॉर्ड

19

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

C ++ समुदाय के भीतर 'अपवाद सुरक्षित' कोड के बारे में अधिक बात हो सकती है, लेकिन यह अन्य भाषाओं में लगभग समान रूप से महत्वपूर्ण है जिनमें अपवाद हैं। 'अपवाद सुरक्षित' कोड का संपूर्ण बिंदु यह है कि आप सोचते हैं कि यदि आपका कोई फ़ंक्शन / विधियों में कोई अपवाद उत्पन्न होता है तो आपका कोड किस अवस्था में छोड़ दिया जाता है।
C ++ में, 'अपवाद सुरक्षित' कोड थोड़ा अधिक महत्वपूर्ण है, क्योंकि C ++ में स्वचालित कचरा संग्रह नहीं है जो उन वस्तुओं का ध्यान रखता है जो अपवाद के कारण अनाथ हो गए हैं।

C ++ समुदाय में अपवाद सुरक्षा के बारे में अधिक चर्चा करने का कारण संभवतः इस तथ्य से भी है कि C ++ में आपको अधिक जानकारी होनी चाहिए कि क्या गलत हो सकता है, क्योंकि भाषा में डिफ़ॉल्ट सुरक्षा जाल कम हैं।


2
नोट: कृपया यह न सोचें कि C ++ में नियतात्मक विध्वंसक हैं। ऑब्जेक्ट पास्कल / डेल्फी में नियतात्मक विध्वंसक भी होते हैं जो अभी भी 'अंत' का समर्थन करते हैं, बहुत अच्छे कारणों के लिए मैंने नीचे अपनी पहली टिप्पणियों में समझाया था।
वेक्टर

13
@ माइक: यह देखते हुए कि कभी भी finallyC ++ मानक में जोड़ने का प्रस्ताव नहीं आया है, मुझे लगता है कि यह निष्कर्ष निकालना सुरक्षित है कि C ++ समुदाय the absence of finallyसमस्या को दूर नहीं करता है। अधिकांश भाषाओं में finallyC ++ के संगत नियतात्मक विनाश का अभाव है। मैं देख रहा हूं कि डेल्फी उन दोनों के पास है, लेकिन मैं इसके इतिहास को अच्छी तरह से नहीं जानता कि जो पहले था।
बार्ट वैन इनगेन शेनॉ

3
डेखी स्टैक आधारित वस्तुओं का समर्थन नहीं करती है - केवल ढेर आधारित है, और स्टैक पर ऑब्जेक्ट संदर्भ हैं। इसलिए जब उचित हो तब विध्वंसकारियों को स्पष्ट रूप से आह्वान करना आवश्यक है।
वेक्टर

2
C ++ में पूरी तरह से cruft है जो यकीनन जरूरी नहीं है, इसलिए यह सही उत्तर नहीं हो सकता है।
काज

15
दो दशकों से अधिक समय में मैंने भाषा का उपयोग किया है, और अन्य लोगों के साथ काम किया है जो भाषा का उपयोग करते हैं, मैंने कभी भी काम करने वाले C ++ प्रोग्रामर का सामना नहीं किया है जिन्होंने कहा था "मुझे वास्तव में भाषा की इच्छा थी finally"। मैं कभी भी किसी भी कार्य को याद नहीं कर सकता हूं जो इसे आसान बना देता, मुझे इसकी पहुंच थी।
रोबोट

12

अन्य लोगों ने समाधान के रूप में RAII पर चर्चा की है। यह पूरी तरह से एक अच्छा उपाय है। लेकिन यह वास्तव में संबोधित नहीं करता है कि वे क्यों नहीं जोड़े गए finallyक्योंकि यह एक व्यापक रूप से वांछित चीज है। इसका उत्तर C ++ के डिज़ाइन और विकास के लिए अधिक मौलिक है: C ++ के विकास के दौरान, इसमें शामिल लोगों ने डिज़ाइन सुविधाओं की शुरूआत का दृढ़ता से विरोध किया है, जो कि भारी मात्रा में उपद्रव के बिना अन्य सुविधाओं का उपयोग करके प्राप्त किया जा सकता है और विशेष रूप से जहां इसके लिए परिचय की आवश्यकता होती है। नए कीवर्ड जो पुराने कोड को असंगत प्रस्तुत कर सकते हैं। चूंकि RAII एक अत्यधिक कार्यात्मक विकल्प प्रदान करता है finallyऔर आप वास्तव finallyमें C ++ 11 में अपना स्वयं का रोल कर सकते हैं , वैसे भी इसके लिए बहुत कम समय था।

आपको बस एक ऐसा वर्ग बनाने की जरूरत है, Finallyजो इसे पारित करने वाले फ़ंक्शन को कॉल करे जिसमें यह विध्वंसक हो। तो आप यह कर सकते हैं:

try
{
    Finally atEnd([&] () { database.close(); });

    database.doRisky();
}

हालांकि, अधिकांश मूल C ++ प्रोग्रामर, साफ-सुथरे डिजाइन वाली RAII वस्तुएं पसंद करेंगे।


3
आप अपने लैम्ब्डा में संदर्भ कैप्चर को याद कर रहे हैं। यह Finally atEnd([&] () { database.close(); });भी होना चाहिए , मुझे लगता है कि निम्नलिखित बेहतर है: { Finally atEnd(...); try {...} catch(e) {...} }(मैंने ट्राइ-ब्लॉक से अंतिम रूप से उठा लिया ताकि यह कैच ब्लॉकों को निष्पादित करे।)
थॉमस ईडिंग सेप

2

आप "ट्रैप" पैटर्न का उपयोग कर सकते हैं - भले ही आप कोशिश / कैच ब्लॉक का उपयोग नहीं करना चाहते हों।

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


1
यह सवाल का जवाब नहीं देता है, और बस साबित करता है कि आखिरकार ऐसा बुरा विचार नहीं है ...
वेक्टर

2

ठीक है, आप finallyलैंबडास का उपयोग करते हुए रोल- योर - ओन की तरह कर सकते हैं, जो ठीक संकलन करने के लिए निम्नलिखित मिलेगा (उदाहरण के लिए RAII के बिना, कोड का सबसे अच्छा टुकड़ा नहीं):

{
    FILE *file = fopen("test","w");

    finally close_the_file([&]{
        cout << "We're closing the file in a pseudo-finally clause." << endl;
        fclose(file);
    });
}

इस लेख को देखें ।


-2

मुझे यकीन नहीं है कि मैं यहां इस बात से सहमत हूं कि RAII एक सुपरसेट है finally। RAII की ऊँची एड़ी के जूते सरल है: अपवाद। आरएआई को विध्वंसक के साथ लागू किया जाता है, और विध्वंसक से बाहर फेंकने के लिए सी ++ में हमेशा गलत होता है। इसका मतलब है कि जब आप अपने क्लीनअप कोड को फेंकने के लिए आवश्यकता होती है तो आप RAII का उपयोग नहीं कर सकते। यदि finallyलागू किया गया था, तो दूसरी ओर, यह मानने का कोई कारण नहीं है कि finallyब्लॉक से फेंकना कानूनी नहीं होगा ।

इस तरह एक कोड पथ पर विचार करें:

void foo() {
    try {
        ... stuff ...
        complex_cleanup();
    } catch (A& a) {
        handle_a(a);
        complex_cleanup();
        throw;
    } catch (B& b) {
        handle_b(b);
        complex_cleanup();
        throw;
    } catch (...) {
        handle_generic();
        complex_cleanup();
        throw;
    }
}

अगर हमारे पास होता finallyतो हम लिख सकते थे :

void foo() {
    try {
        ... stuff ...
    } catch (A& a) {
        handle_a(a);
        throw;
    } catch (B& b) {
        handle_b(b);
        throw;
    } catch (...) {
        handle_generic();
        throw;
    } finally {
        complex_cleanup();
    }
}

लेकिन कोई रास्ता नहीं है, कि मैं आरएआई का उपयोग करके समान व्यवहार प्राप्त कर सकूं।

यदि कोई जानता है कि यह C ++ में कैसे किया जाता है, तो मुझे उत्तर में बहुत दिलचस्पी है। मैं उदाहरण के लिए, उस पर भरोसा करने वाली किसी चीज़ से खुश होऊंगा, जो कि कुछ विशेष क्षमताओं या कुछ के साथ एक एकल वर्ग से विरासत में मिले सभी अपवादों को लागू करता है।


1
अपने दूसरे उदाहरण में, यदि complex_cleanupआप फेंक सकते हैं, तो आपके पास एक ऐसा मामला हो सकता है जहां दो बिना शर्त अपवाद एक बार में उड़ान में हों, जैसे कि आप RAII / विध्वंसक के साथ होंगे, और C ++ ने इसे अनुमति देने से इनकार कर दिया। यदि आप चाहते हैं कि मूल अपवाद देखा जाए, तो complex_cleanupकिसी भी अपवाद को रोकना चाहिए, जैसे कि RAII / विनाशकों के साथ। यदि आप चाहते हैं कि complex_cleanupअपवाद देखा जाए, तो मुझे लगता है कि आप नेस्टेड ट्राई / कैच ब्लॉक्स का उपयोग कर सकते हैं - हालाँकि यह एक टिप्पणी में फिट होने के लिए एक स्पर्शरेखा और कठिन है, इसलिए यह एक अलग प्रश्न के लायक है।
जोश केली

मैं पहले उदाहरण के रूप में समान व्यवहार प्राप्त करने के लिए RAII का उपयोग करना चाहता हूं, अधिक सुरक्षित रूप से। पुटेटिव finallyब्लॉक में एक फेंक स्पष्ट रूप से catchब्लॉक-इन WRT इन-फ्लाइट अपवादों में एक फेंक के रूप में ही काम करेगा - कॉल नहीं std::terminate। प्रश्न " finallyC ++ में क्यों नहीं है?" और जवाब सभी कहते हैं "आपको इसकी आवश्यकता नहीं है ... RAII FTW!" मेरा कहना है कि हाँ, RAII मेमोरी मैनेजमेंट जैसे सरल मामलों के लिए ठीक है, लेकिन जब तक अपवादों का मुद्दा हल नहीं हो जाता है, तब तक इसे एक सामान्य उद्देश्य के समाधान के लिए बहुत अधिक विचार / ओवरहेड / चिंता / पुनः डिजाइन की आवश्यकता होती है।
मैडिसिनिस्ट

3
मैं आपकी बात समझता हूं - विनाशकारी के साथ कुछ वैध मुद्दे हैं जो फेंक सकते हैं - लेकिन वे दुर्लभ हैं। यह कहना कि RAII + अपवादों में अनसुलझे मुद्दे हैं या यह कि RAII एक सामान्य-उद्देश्य समाधान नहीं है, बस अधिकांश C ++ डेवलपर्स के अनुभव से मेल नहीं खाता है।
जोश केली

1
यदि आप अपने आप को विनाशकों में अपवादों को बढ़ाने की आवश्यकता के साथ पाते हैं, तो आप कुछ गलत कर रहे हैं - संभवतः अन्य स्थानों पर पॉइंटर्स का उपयोग कर रहे हैं जब वे आवश्यक नहीं हैं।
वेक्टर

1
यह टिप्पणियों के लिए भी शामिल है। इसके बारे में एक प्रश्न पोस्ट करें : आप RAII मॉडल का उपयोग करके C ++ में इस परिदृश्य को कैसे संभालेंगे ... यह काम नहीं करता है ... फिर से, आपको अपनी टिप्पणियों को निर्देशित करना चाहिए : आप जिस सदस्य से बात कर रहे हैं उसका नाम @ लिखें और लिखें अपनी टिप्पणी की शुरुआत में। जब टिप्पणियां आपके स्वयं के पोस्ट पर होती हैं, तो आपको सब कुछ अधिसूचित हो जाता है, लेकिन अन्य तब तक नहीं करते जब तक आप उन्हें टिप्पणी नहीं देते।
वेक्टर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.