मैं एक फ़ंक्शन के लिए एक साझा पॉइंटर पास करना चाहता हूं। क्या उसके लिए आपके द्वारा मेरी मदद की जाएगी?
ज़रूर, मैं आपकी मदद कर सकता हूं। मुझे लगता है कि आपको C ++ में स्वामित्व शब्दार्थ की कुछ समझ है। क्या यह सच है?
हाँ, मैं इस विषय के साथ काफी सहज हूं।
अच्छा।
ठीक है, मैं shared_ptrतर्क लेने के लिए केवल दो कारणों के बारे में सोच सकता हूं :
- फ़ंक्शन ऑब्जेक्ट का स्वामित्व साझा करना चाहता है;
- फ़ंक्शन कुछ ऑपरेशन करता है जो विशेष रूप से
shared_ptrs पर काम करता है ।
आप किस में रुचि रखते हैं?
मैं एक सामान्य उत्तर की तलाश में हूं, इसलिए मुझे वास्तव में दोनों में दिलचस्पी है। मैं इस मामले में उत्सुक हूं कि आपके मामले में # 2 का क्या मतलब है।
ऐसे कार्यों के उदाहरणों में शामिल हैं std::static_pointer_cast, कस्टम तुलनित्र, या विधेय। उदाहरण के लिए, यदि आपको एक वेक्टर से सभी अनूठे शेयर्ड_एप्ट्र को खोजने की आवश्यकता है, तो आपको इस तरह के एक विधेय की आवश्यकता है।
आह, जब फ़ंक्शन को वास्तव में खुद स्मार्ट पॉइंटर को हेरफेर करने की आवश्यकता होती है।
बिल्कुल सही।
उस मामले में, मुझे लगता है कि हमें संदर्भ से गुजरना चाहिए।
हाँ। और अगर यह पॉइंटर नहीं बदलता है, तो आप कॉन्स्ट रेफरेंस से गुजरना चाहते हैं। जब से आपको स्वामित्व साझा करने की आवश्यकता नहीं है, तब तक कॉपी करने की कोई आवश्यकता नहीं है। वह दूसरा परिदृश्य है।
ठीक मिल गया। दूसरे परिदृश्य के बारे में बात करते हैं।
वह जहां आप स्वामित्व साझा करते हैं? ठीक। आप स्वामित्व कैसे साझा करते हैं shared_ptr?
इसकी नकल करके।
फिर फ़ंक्शन को एक की प्रतिलिपि बनाने की आवश्यकता होगी shared_ptr, सही?
जाहिर है। तो मैं इसे एक कॉन्स्टेबल और एक स्थानीय वैरिएबल को कॉपी करने के संदर्भ में पास करता हूं?
नहीं, वह निराशावाद है। यदि इसे संदर्भ द्वारा पारित किया जाता है, तो फ़ंक्शन को कॉपी मैन्युअल रूप से बनाने के अलावा कोई विकल्प नहीं होगा। यदि यह मान से पारित हो जाता है तो संकलक एक प्रतिलिपि और एक चाल के बीच सबसे अच्छा विकल्प चुन लेगा और स्वचालित रूप से प्रदर्शन करेगा। तो, मूल्य से गुजारें।
अच्छी बात। मुझे याद रखना चाहिए कि " वांट स्पीड? पास बाय वैल्यू। " लेख अधिक बार।
प्रतीक्षा करें, क्या होगा यदि फ़ंक्शन shared_ptrएक सदस्य चर में संग्रहीत करता है, उदाहरण के लिए? क्या यह एक निरर्थक प्रति नहीं होगी?
फ़ंक्शन केवल shared_ptrतर्क को उसके संग्रहण में स्थानांतरित कर सकता है। एक चलती shared_ptrसस्ता है, क्योंकि यह किसी भी संदर्भ में गिना जाता है नहीं बदलता है।
आह, अच्छा विचार है।
लेकिन मैं तीसरे परिदृश्य के बारे में सोच रहा हूं: क्या होगा यदि आप इसमें हेरफेर नहीं करना चाहते हैं shared_ptr, न ही स्वामित्व साझा करना चाहते हैं?
उस मामले में, shared_ptrफ़ंक्शन के लिए पूरी तरह से अप्रासंगिक है। यदि आप पॉइन्टी को हेरफेर करना चाहते हैं, तो एक पॉइन्टी लें, और कॉल करने वालों को यह चुनें कि उन्हें क्या स्वामित्व स्वामित्व चाहिए।
और क्या मुझे संदर्भ द्वारा या मूल्य के आधार पर सूचक को लेना चाहिए?
सामान्य नियम लागू होते हैं। स्मार्ट संकेत कुछ भी नहीं बदलते हैं।
यदि मैं प्रतिलिपि बनाने जा रहा हूं, तो मान से पास करें यदि मैं प्रतिलिपि से बचना चाहता हूं तो संदर्भ द्वारा पास करें।
सही।
हम्म। मुझे लगता है कि आप अभी तक एक और परिदृश्य भूल गए। क्या होगा यदि मैं स्वामित्व साझा करना चाहता हूं, लेकिन केवल एक निश्चित शर्त पर निर्भर करता है?
आह, एक दिलचस्प बढ़त का मामला। मुझे उम्मीद नहीं है कि अक्सर ऐसा होगा। लेकिन जब ऐसा होता है तो आप या तो मान से गुजर सकते हैं और यदि आपको इसकी आवश्यकता नहीं है, तो कॉपी को अनदेखा कर सकते हैं, या संदर्भ द्वारा पास कर सकते हैं और यदि आपको इसकी आवश्यकता है तो प्रतिलिपि बना सकते हैं।
मैं पहले विकल्प में एक निरर्थक कॉपी को जोखिम में डालता हूं, और दूसरे में एक संभावित कदम खो देता हूं। क्या मैं केक नहीं खा सकता और यह भी है?
यदि आप ऐसी स्थिति में हैं जहां यह वास्तव में मायने रखता है, तो आप दो अधिभार प्रदान कर सकते हैं, एक कॉन्स्टल लेवल्यू रेफरेंस ले रहा है, और दूसरा रिविल्यू रेफरेंस ले रहा है। एक कॉपी करता है, दूसरा चलता है। एक सही-अग्रेषण फ़ंक्शन टेम्पलेट एक और विकल्प है।
मुझे लगता है कि सभी संभावित परिदृश्यों को शामिल किया गया है। आपका बहुत बहुत धन्यवाद।
const std::shared_ptr<myClass>& arg1