C ++ में किसी फ़ंक्शन में पैरामीटर पास करने के तीन तरीके हैं: मूल्य द्वारा, लैवल्यू संदर्भ द्वारा, और रेवल्यू संदर्भ द्वारा। इनमें से, मूल्य से गुजरना इस अर्थ में स्वामित्व बनाता है कि कहा गया फ़ंक्शन अपनी प्रति प्राप्त करता है, और प्रतिद्वंद्विता संदर्भ से गुजरना इंगित करता है कि मूल्य का उपभोग किया जा सकता है, अर्थात अब कॉलर द्वारा उपयोग नहीं किया जाएगा। लैवल्यू रेफरेंस से गुजरने का मतलब है कि ऑब्जेक्ट को कॉलर से अस्थायी रूप से उधार लिया गया है।
हालाँकि, ये "कन्वेंशन द्वारा" होते हैं और हमेशा कंपाइलर द्वारा जांचे नहीं जा सकते। और आप गलती से एक लैवल्यू संदर्भ को एक रवैल्यू संदर्भ में बदल सकते हैं std::move()
। लगातार, तीन समस्याएं हैं:
एक संदर्भ वस्तु को संदर्भित कर सकता है। रस्ट का जीवनकाल प्रणाली इसे रोकता है।
किसी भी समय एक से अधिक परस्पर / गैर-कॉन्स्टेबल संदर्भ सक्रिय हो सकते हैं। रस्ट का उधार चेकर इसे रोकता है।
आप संदर्भों से बाहर नहीं निकल सकते। आप एक कॉल साइट पर नहीं देख सकते हैं कि क्या यह फ़ंक्शन आपके फ़ंक्शन के लिए एक संदर्भ बनाता है, जिसे बिना किसी फ़ंक्शन के हस्ताक्षर के बिना जाना जाता है। इसलिए आप न तो संदर्भों को रोक सकते हैं, न ही अपनी कक्षाओं के किसी विशेष तरीके को हटाकर और न ही कुछ "नो रेफरेंस" स्टाइल गाइड के अनुपालन के लिए कॉल साइट का ऑडिट करके।
जीवनकाल की समस्या बुनियादी स्मृति सुरक्षा के बारे में है। जब संदर्भित ऑब्जेक्ट की समय सीमा समाप्त हो गई है तो संदर्भ का उपयोग करना अवैध है। लेकिन जीवनकाल के बारे में भूलना बहुत आसान है जब आप किसी वस्तु के भीतर एक संदर्भ संग्रहीत करते हैं, विशेष रूप से जब वह वस्तु वर्तमान गुंजाइश को रेखांकित करती है। C ++ टाइप सिस्टम इसके लिए जिम्मेदार नहीं हो सकता क्योंकि यह ऑब्जेक्ट लाइफटाइम को बिल्कुल भी मॉडल नहीं करता है।
std::weak_ptr
स्मार्ट सूचक एक सादे संदर्भ के लिए इसी तरह एनकोड स्वामित्व अर्थ विज्ञान करता है, लेकिन जरूरी है कि संदर्भित वस्तु एक के माध्यम से किया जाता है shared_ptr
, यानी संदर्भ बार गणना है। यह एक शून्य लागत अमूर्तता नहीं है।
हालांकि C ++ में एक कास्ट सिस्टम है, यह ट्रैक नहीं करता है कि किसी ऑब्जेक्ट को संशोधित किया जा सकता है, लेकिन यह ट्रैक करता है कि किसी ऑब्जेक्ट को उस विशेष संदर्भ के माध्यम से संशोधित किया जा सकता है या नहीं । "निडर संगति" के लिए पर्याप्त गारंटी प्रदान नहीं करता है। इसके विपरीत, रस्ट गारंटी देता है कि यदि कोई सक्रिय परिवर्तनशील संदर्भ है जो केवल संदर्भ है ("मैं केवल एक ही हूं जो इस ऑब्जेक्ट को बदल सकता है") और यदि गैर-परस्पर संदर्भ हैं तो ऑब्जेक्ट के सभी संदर्भ गैर-परस्पर हैं ("जब मैं ऑब्जेक्ट से पढ़ सकता हूं, तो कोई भी इसे बदल नहीं सकता है")।
C ++ में आपको किसी म्यूटेक्स के साथ स्मार्ट पॉइंटर के माध्यम से किसी ऑब्जेक्ट तक पहरा देने का प्रलोभन दिया जा सकता है। लेकिन जैसा कि ऊपर एक बार चर्चा की जा चुकी है कि हम इसके अपेक्षित जीवनकाल से बच सकते हैं। इसलिए ऐसा स्मार्ट पॉइंटर गारंटी नहीं दे सकता है कि यह अपने प्रबंधित ऑब्जेक्ट तक पहुंच का एकल बिंदु है। इस तरह की योजना वास्तव में व्यवहार में काम कर सकती है क्योंकि अधिकांश प्रोग्रामर खुद को तोड़फोड़ नहीं करना चाहते हैं, लेकिन एक प्रकार-प्रणाली के दृष्टिकोण से यह अभी भी पूरी तरह से निराधार नहीं है।
स्मार्ट पॉइंटर्स के साथ सामान्य समस्या यह है कि वे मुख्य भाषा के शीर्ष पर लाइब्रेरी हैं। मुख्य भाषा सुविधाओं का सेट इन स्मार्ट पॉइंटर्स को सक्षम करता है, उदाहरण के std::unique_ptr
लिए मूव-कंस्ट्रक्टर की आवश्यकता होती है। लेकिन वे मुख्य भाषा के भीतर की कमियों को ठीक नहीं कर सकते हैं। किसी फ़ंक्शन को कॉल करते समय और संदर्भ को एक साथ लटकाने के लिए संदर्भों को स्पष्ट रूप से बनाने की क्षमता का मतलब है कि कोर सी ++ भाषा निराधार है। किसी एक के लिए परस्पर संदर्भों को सीमित करने में असमर्थता का मतलब है कि C ++ किसी भी प्रकार की संगामिति के साथ दौड़ की स्थिति के खिलाफ सुरक्षा की गारंटी नहीं दे सकता है।
बेशक कई मामलों में C ++ और Rust एक जैसे होते हैं, विशेषकर सांख्यिकीय रूप से निर्धारित वस्तु जीवन काल की उनकी अवधारणाओं के बारे में। लेकिन जब तक सही सी ++ प्रोग्राम लिखना संभव है (बशर्ते कि कोई भी प्रोग्रामर कोई गलती नहीं करता है), रुस्ट चर्चा की गई संपत्तियों के बारे में शुद्धता की गारंटी देता है ।