स्ट्रॉस्ट्रुप ने 2013 गोइंग नेटिव सम्मेलन में इस पर कुछ अच्छी टिप्पणियां कीं।
बस इस वीडियो में लगभग 25m50s पर जाएं । (मैं वास्तव में पूरे वीडियो को देखने की सलाह दूंगा, लेकिन यह कचरा संग्रहण के बारे में पूरी जानकारी देता है।)
जब आपके पास वास्तव में एक महान भाषा है जो इसे आसान (और सुरक्षित, और पूर्वानुमान योग्य, और आसानी से पढ़ा जाने वाला, और आसानी से पढ़ाना) वस्तुओं और मूल्यों से सीधे तरीके से निपटना है, तो (स्पष्ट) उपयोग से बचें ढेर, तो आप भी कचरा संग्रह नहीं चाहते हैं ।
आधुनिक C ++, और हमारे पास C ++ 11 में सामान के साथ, कचरा संग्रह अब सीमित परिस्थितियों में छोड़कर वांछनीय नहीं है। वास्तव में, भले ही एक अच्छा कचरा संग्रहकर्ता प्रमुख C ++ संकलक में से एक में बनाया गया हो, मुझे लगता है कि इसका उपयोग बहुत बार नहीं किया जाएगा। जीसी से बचना आसान होगा , कठिन नहीं।
वह इस उदाहरण को दर्शाता है:
void f(int n, int x) {
Gadget *p = new Gadget{n};
if(x<100) throw SomeException{};
if(x<200) return;
delete p;
}
यह C ++ में असुरक्षित है। लेकिन यह जावा में भी असुरक्षित है! C ++ में, यदि फ़ंक्शन जल्दी लौटता है, तो delete
कभी भी कॉल नहीं किया जाएगा। लेकिन अगर आपके पास पूरा कचरा संग्रह है, जैसे कि जावा में, आपको केवल एक सुझाव मिलता है कि ऑब्जेक्ट "भविष्य में किसी बिंदु पर" नष्ट हो जाएगा ( अपडेट करें: यह और भी बुरा है कि यह जावा नहीं करता है।फाइनली को कभी भी फोन करने का वादा - यह शायद कभी नहीं बुलाया जाएगा)। यह काफी अच्छा नहीं है अगर गैजेट एक ओपन फाइल हैंडल, या एक डेटाबेस, या डेटा से जुड़ा होता है, जिसे आपने बाद के बिंदु पर डेटाबेस में लिखने के लिए बफ़र किया है। हम चाहते हैं कि गैजेट समाप्त होते ही नष्ट हो जाए, ताकि इन संसाधनों को जल्द से जल्द मुक्त किया जा सके। आप अपने डेटाबेस सर्वर को हजारों डेटाबेस कनेक्शनों के साथ संघर्ष नहीं करना चाहते हैं जिनकी अब आवश्यकता नहीं है - यह नहीं जानता कि आपका प्रोग्राम काम कर रहा है।
तो उपाय क्या है? कुछ दृष्टिकोण हैं। स्पष्ट दृष्टिकोण, जिसे आप अपनी अधिकांश वस्तुओं के लिए उपयोग करेंगे:
void f(int n, int x) {
Gadget p = {n}; // Just leave it on the stack (where it belongs!)
if(x<100) throw SomeException{};
if(x<200) return;
}
यह टाइप करने के लिए कम वर्ण लेता है। यह new
रास्ते में नहीं हो रहा है। यह आपको Gadget
दो बार टाइप करने की आवश्यकता नहीं है । फ़ंक्शन के अंत में ऑब्जेक्ट को नष्ट कर दिया जाता है। यदि आप यही चाहते हैं, तो यह बहुत सहज है। Gadget
के रूप में ही व्यवहार करते हैं int
या double
। भविष्य कहनेवाला, आसानी से पढ़ा जाने वाला, आसानी से पढ़ाने वाला। सब कुछ एक 'मूल्य' है। कभी-कभी एक बड़ा मूल्य, लेकिन मूल्यों को सिखाना आसान होता है क्योंकि आपके पास यह 'कार्रवाई दूरी पर' चीज नहीं है जो आपको संकेत (या संदर्भ) के साथ मिलती है।
आपके द्वारा बनाई गई अधिकांश वस्तुएं केवल उस फ़ंक्शन में उपयोग के लिए हैं जो उन्हें बनाया गया है, और शायद बाल कार्यों के इनपुट के रूप में पारित किया गया है। प्रोग्रामर को वस्तुओं को वापस करते समय 'मेमोरी मैनेजमेंट' के बारे में नहीं सोचना चाहिए, या अन्यथा सॉफ़्टवेयर के व्यापक रूप से अलग हिस्सों में वस्तुओं को साझा करना चाहिए।
स्कोप और आजीवन महत्वपूर्ण हैं। अधिकांश समय, यह आसान है अगर जीवनकाल गुंजाइश के समान है। यह समझना आसान है और सिखाना आसान है। जब आप एक अलग जीवनकाल चाहते हैं, तो स्पष्ट रूप से उस कोड को पढ़ना चाहिए जो आप ऐसा कर रहे हैं, shared_ptr
उदाहरण के लिए। (या मूविंग (बड़ी) ऑब्जेक्ट्स को वैल्यू के आधार पर, मूवमेंट-सेमेंटिक्स का लाभ उठाते हुए या unique_ptr
।
यह एक दक्षता समस्या की तरह लग सकता है। क्या होगा अगर मैं एक गैजेट को वापस करना चाहता हूं foo()
? C ++ 11 के चाल शब्दार्थ बड़ी वस्तुओं को वापस करना आसान बनाते हैं। बस लिखें Gadget foo() { ... }
और यह सिर्फ काम करेगा, और जल्दी से काम करेगा। आपको &&
खुद के साथ गड़बड़ करने की ज़रूरत नहीं है , बस चीजों को मूल्य से वापस करें और भाषा अक्सर आवश्यक अनुकूलन कर पाएगी। (C ++ 03 से पहले भी, कंपाइलरों ने अनावश्यक नकल से बचने के लिए उल्लेखनीय रूप से अच्छा काम किया।)
जैसा कि स्ट्रॉस्ट्रप ने वीडियो में कहीं और कहा है (विरोधाभासी): "केवल एक कंप्यूटर वैज्ञानिक एक वस्तु की नकल करने पर जोर देगा, और फिर मूल को नष्ट कर देगा। (दर्शक हँसते हैं)। बस वस्तु को सीधे नए स्थान पर क्यों नहीं ले जाना है? यह मनुष्य है (कंप्यूटर वैज्ञानिक नहीं) उम्मीद करते हैं। "
जब आप गारंटी दे सकते हैं कि किसी वस्तु की केवल एक प्रति की आवश्यकता है, तो वस्तु के जीवनकाल को समझना बहुत आसान है। आप जो चाहें जीवन भर की नीति चुन सकते हैं और यदि आप चाहते हैं तो कचरा संग्रह है। लेकिन जब आप अन्य दृष्टिकोणों के लाभों को समझते हैं, तो आप पाएंगे कि कचरा संग्रह आपकी प्राथमिकताओं की सूची में सबसे नीचे है।
यदि यह आप के लिए काम नहीं करता है, तो आप उपयोग कर सकते हैं unique_ptr
, या उस में नाकाम रहने, shared_ptr
। अच्छी तरह से लिखा C ++ 11 कम है, पढ़ने में आसान है, और स्मृति प्रबंधन की बात आती है तो कई अन्य भाषाओं की तुलना में आसान है।