क्या मुझे सदस्य डेटा में संकेत या संदर्भ पसंद करना चाहिए?


138

प्रश्न को स्पष्ट करने के लिए यह एक सरल उदाहरण है:

class A {};

class B
{
    B(A& a) : a(a) {}
    A& a;
};

class C
{
    C() : b(a) {} 
    A a;
    B b; 
};

तो B, C का एक हिस्सा अपडेट करने के लिए जिम्मेदार है। मैंने लिंट के माध्यम से कोड चलाया और यह संदर्भ सदस्य के बारे में फुसफुसाया: lint # 1725 । यह डिफ़ॉल्ट कॉपी और असाइनमेंट की देखभाल करने के बारे में बात करता है जो काफी हद तक सही है, लेकिन डिफ़ॉल्ट कॉपी और असाइनमेंट पॉइंटर्स के साथ भी खराब है, इसलिए वहां बहुत कम फायदा है।

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

मैं आमतौर पर केवल सदस्य डेटा में एक पॉइंटर का उपयोग करता हूं जब पॉइंटर शून्य हो सकता है या बदल सकता है। क्या डेटा सदस्यों के संदर्भों पर संकेत पसंद करने के लिए कोई अन्य कारण हैं?

क्या यह कहना सही है कि किसी संदर्भ वाली वस्तु को असाइन नहीं किया जाना चाहिए, क्योंकि संदर्भ को एक बार प्रारंभ करने के बाद नहीं बदला जाना चाहिए?


"लेकिन डिफ़ॉल्ट कॉपी और असाइनमेंट पॉइंटर्स के साथ भी खराब है": यह समान नहीं है: जब भी आप कास्ट नहीं करते हैं तो एक पॉइंटर को बदला जा सकता है। एक संदर्भ आम तौर पर हमेशा संकुचित होता है! (यदि आप अपने सदस्य को "A & const a" में बदलने का प्रयास करते हैं, तो आप यह देखेंगे कि संकलक (कम से कम GCC) आपको चेतावनी देगा कि संदर्भ वैसे भी "const" कीवर्ड के बिना const है।
mmmmmmmm

इसके साथ मुख्य समस्या यह है कि अगर कोई बी बी (ए ()) करता है, तो आप खराब हो जाते हैं क्योंकि आप एक झूलते हुए संदर्भ के साथ समाप्त हो रहे हैं।
log0

जवाबों:


67

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

उदाहरण की समस्याएं:

  • आपको प्रत्येक निर्माता की प्रारंभिक सूची में संदर्भ को इनिशियलाइज़ करने के लिए मजबूर किया जाता है: इस आरंभीकरण को किसी अन्य फ़ंक्शन में फैक्टर करने का कोई तरीका नहीं है ( C ++ 0x तक, वैसे भी संपादित करें: C ++ में अब प्रतिनिधि बनाने वाले हैं )
  • संदर्भ पलटाव या शून्य नहीं हो सकता। यह एक फायदा हो सकता है, लेकिन अगर कोड को कभी रिबॉन्डिंग की अनुमति देने के लिए या सदस्य को शून्य होने की आवश्यकता होती है, तो सदस्य के सभी उपयोगों को बदलने की आवश्यकता होती है
  • सूचक सदस्यों के विपरीत, संदर्भों को आसानी से स्मार्ट पॉइंटर्स या पुनरावृत्तियों द्वारा प्रतिस्थापित नहीं किया जा सकता है क्योंकि रिफैक्टिंग की आवश्यकता हो सकती है
  • जब भी किसी संदर्भ का उपयोग किया जाता है तो वह मूल्य प्रकार ( .ऑपरेटर आदि) की तरह दिखता है , लेकिन एक पॉइंटर की तरह व्यवहार कर सकता है (झूल सकता है) - इसलिए Google स्टाइल गाइड इसे हतोत्साहित करता है

66
आपके द्वारा उल्लिखित सभी चीजें बचने के लिए अच्छी चीजें हैं, इसलिए यदि संदर्भ इसमें मदद करते हैं - वे अच्छे हैं और बुरे नहीं हैं। डेटा को अंकित करने के लिए प्रारंभिक सूची सबसे अच्छी जगह है। बहुत बार आपको असाइनमेंट ऑपरेटर को छिपाना पड़ता है, ऐसे संदर्भों के साथ जो आपके पास नहीं हैं। "रिबाउंड नहीं किया जा सकता" - अच्छा, चर का पुन: उपयोग एक बुरा विचार है।
मायकोला गोलूबेव

4
@ मायकोला: मैं आपसे सहमत हूं। मैं सदस्यों को शुरुआती सूचियों में आरंभ करने के लिए पसंद करता हूं, मैं अशक्त बिंदुओं से बचता हूं और यह निश्चित रूप से एक चर के लिए अच्छा नहीं है कि इसका अर्थ बदल जाए। जहां हमारी राय अलग है कि मुझे मेरे लिए इसे लागू करने की आवश्यकता नहीं है या संकलक नहीं चाहिए। यह लिखने में किसी भी वर्ग को आसान नहीं बनाता है, मैं इस क्षेत्र में कीड़े नहीं आया हूं जो इसे पकड़ लेगा, और कभी-कभी मैं उस लचीलेपन की सराहना करता हूं जो मुझे कोड से मिलता है जो लगातार सूचक सदस्यों का उपयोग करता है (स्मार्ट पॉइंटर्स जहां उपयुक्त है)।
जेम्स हॉपकिन

मुझे लगता है कि असाइनमेंट को छिपाना नहीं एक संगीन तर्क है क्योंकि आपको असाइनमेंट को छिपाने की ज़रूरत नहीं है अगर क्लास में एक पॉइंटर होता है जो इसे वैसे भी हटाने के लिए ज़िम्मेदार नहीं है - डिफ़ॉल्ट करेगा। मुझे लगता है कि यह सबसे अच्छा जवाब है क्योंकि यह अच्छे कारण देता है कि क्यों सदस्य डेटा में संदर्भों पर प्राथमिकता दी जानी चाहिए।
markh44

4
जेम्स, ऐसा नहीं है कि यह कोड को लिखना आसान बनाता है यह कोड को पढ़ने में आसान बनाता है। एक डेटा सदस्य के रूप में एक संदर्भ के साथ आपको कभी आश्चर्य नहीं होगा कि क्या यह उपयोग के बिंदु पर शून्य हो सकता है। इसका मतलब है कि आप आवश्यक संदर्भ के साथ कोड को देख सकते हैं।
लेन होल्गेट

4
यह इकाई परीक्षण करता है और बहुत कठिन, असंभव को लगभग इस बात पर निर्भर करता है कि कितने उपयोग किए जाते हैं, 'ग्राफ विस्फोट को प्रभावित' के साथ मिलकर IMHO उन्हें उपयोग नहीं करने के लिए पर्याप्त कारण मजबूर कर रहे हैं।
क्रिस हुआंग-लीवर

156

अंगूठे का मेरा अपना नियम:

  • एक संदर्भ सदस्य का उपयोग करें जब आप चाहते हैं कि आपकी वस्तु का जीवन अन्य वस्तुओं के जीवन पर निर्भर हो : यह कहने का एक स्पष्ट तरीका है कि आप किसी अन्य वर्ग के मान्य उदाहरण के बिना ऑब्जेक्ट को जीवित रहने की अनुमति नहीं देते हैं - क्योंकि असाइनमेंट और निर्माण के माध्यम से संदर्भ आरंभीकरण प्राप्त करने के लिए दायित्व। यह अपनी कक्षा को किसी अन्य वर्ग के सदस्य होने या नहीं होने के बारे में कुछ भी ग्रहण किए बिना डिजाइन करने का एक अच्छा तरीका है। आप केवल यह मानते हैं कि उनका जीवन अन्य उदाहरणों से सीधे जुड़ा हुआ है। यह आपको बाद में बदलने की अनुमति देता है कि आप अपनी कक्षा का उपयोग कैसे करते हैं (नए के साथ, स्थानीय उदाहरण के रूप में, एक वर्ग के सदस्य के रूप में, एक प्रबंधक में मेमोरी पूल द्वारा उत्पन्न, आदि)
  • अन्य मामलों में पॉइंटर का उपयोग करें : जब आप चाहते हैं कि सदस्य को बाद में बदल दिया जाए, तो एक पॉइंटर या एक कास्ट पॉइंटर का उपयोग करें जो केवल इंगित उदाहरण को पढ़ने के लिए सुनिश्चित हो। यदि वह प्रकार प्रतिलिपि योग्य माना जाता है, तो आप वैसे भी संदर्भ का उपयोग नहीं कर सकते। कभी-कभी आपको एक विशेष फ़ंक्शन कॉल (उदाहरण के लिए init) के बाद सदस्य को इनिशियलाइज़ करने की आवश्यकता होती है और फिर आपके पास पॉइंटर का उपयोग करने के अलावा कोई विकल्प नहीं होता है। लेकिन: गलत सूचक स्थिति का जल्द पता लगाने के लिए अपने सभी सदस्य कार्य में जोर का प्रयोग करें!
  • उन मामलों में जहां आप चाहते हैं कि वस्तु जीवनकाल किसी बाहरी वस्तु के जीवनकाल पर निर्भर हो, और आपको उस प्रकार की प्रतिलिपि बनाने की आवश्यकता भी है, तो सूचक सदस्यों का उपयोग करें, लेकिन निर्माण में संदर्भ तर्क का उपयोग करें जिस तरह से आप निर्माण पर संकेत कर रहे हैं कि इस वस्तु का जीवनकाल निर्भर करता है तर्क के जीवनकाल में BUT कार्यान्वयन उपयोग बिंदुओं को अभी भी प्रतिलिपि योग्य बनाया जा सकता है। जब तक इन सदस्यों को केवल प्रतिलिपि द्वारा बदल दिया जाता है, और आपके प्रकार में एक डिफ़ॉल्ट निर्माता नहीं है, तब तक दोनों लक्ष्यों को पूरा करना चाहिए।

1
मुझे लगता है कि आपके और मायकोला के सही उत्तर हैं और पॉइंटरलेस (कम पॉइंटर पढ़ें) प्रोग्रामिंग को बढ़ावा देते हैं।
अमित

37

वस्तुओं को शायद ही कभी अन्य सामानों की तुलना करने की अनुमति देनी चाहिए। यदि आप 'डिपार्टमेंट', 'एम्प्लॉई', 'डायरेक्टर' जैसी वस्तुओं के साथ कुछ बिजनेस मॉडल पर विचार करते हैं, तो ऐसे मामले की कल्पना करना मुश्किल है जब एक कर्मचारी दूसरे को सौंपा जाएगा।

इसलिए व्यावसायिक वस्तुओं के लिए एक-से-एक और एक-से-कई संबंधों को संदर्भ के रूप में वर्णित करना बहुत अच्छा है और न कि संकेत।

और शायद एक सूचक के रूप में एक-या-शून्य संबंध का वर्णन करना ठीक है।

तो कोई 'हम असाइन नहीं कर सकते' तो कारक।
बहुत सारे प्रोग्रामर केवल पॉइंटर्स के साथ उपयोग किए जाते हैं और यही कारण है कि वे संदर्भ के उपयोग से बचने के लिए कोई भी तर्क पाएंगे।

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


2
+1: वही मैंने अनुभव किया। केवल कुछ सामान्य डेटा संग्रहण वर्गों को असाइनमेंट और कॉपी-कॉटर की आवश्यकता होती है। और अधिक उच्च-स्तरीय व्यावसायिक ऑब्जेक्ट फ्रेमवर्क के लिए प्रतिलिपि बनाने के लिए अन्य तकनीकें होनी चाहिए जो सामान को भी संभालती हैं जैसे "अद्वितीय क्षेत्रों को कॉपी न करें" और "दूसरे माता-पिता को जोड़ें" आदि तो आप अपने व्यवसाय की वस्तुओं की प्रतिलिपि बनाने के लिए उच्च-स्तरीय ढांचे का उपयोग करें। और निम्न-स्तरीय असाइनमेंट को अस्वीकृत करें।
mmmmmmmm

2
+1: समझौते के कुछ बिंदु: एक असाइनमेंट ऑपरेटर को परिभाषित करने से रोकने वाले संदर्भ सदस्य महत्वपूर्ण तर्क नहीं हैं। जैसा कि आप सही ढंग से एक अलग तरीके से बताते हैं, सभी वस्तुओं में मूल्य शब्दार्थ नहीं होते हैं। मैं इस बात से भी सहमत हूं कि हम बिना किसी तार्किक कारण के कोड (कोड) में बिखरे हुए हैं। लेकिन उस के लिए सही दृष्टिकोण वर्ग आक्रमणकारियों के माध्यम से है: एक अच्छी तरह से परिभाषित वर्ग इस बात पर संदेह के लिए कोई जगह नहीं छोड़ेगा कि क्या सदस्य शून्य हो सकते हैं। यदि कोड में कोई भी सूचक शून्य हो सकता है, तो मुझे उम्मीद है कि अच्छी टिप्पणी की जाएगी।
जेम्स हॉपकिन

@JamesHopkin मैं मानता हूं कि अच्छी तरह से डिज़ाइन की गई कक्षाएं पॉइंटर्स का प्रभावी ढंग से उपयोग कर सकती हैं। NULL के खिलाफ रखवाली करने के अलावा, संदर्भ यह भी गारंटी देते हैं कि आपका संदर्भ आरंभीकृत किया गया था (एक सूचक को आरंभीकृत करने की आवश्यकता नहीं है, इसलिए यह किसी और चीज़ की ओर संकेत कर सकता है)। संदर्भ आपको स्वामित्व के बारे में भी बताते हैं - अर्थात् वह वस्तु जिसका सदस्य नहीं है। यदि आप लगातार कुल सदस्यों के लिए संदर्भों का उपयोग करते हैं, तो आपको बहुत अधिक विश्वास होगा कि सूचक सदस्य समग्र वस्तुएं हैं (हालांकि कई मामले नहीं हैं जहां एक समग्र सदस्य एक सूचक द्वारा दर्शाया गया है)।
weberc2

11

7
मैंने पढ़ा था कि लेकिन मुझे लगा कि यह मापदंडों को पार करने के बारे में बात कर रहा है, सदस्य डेटा पर नहीं। "संदर्भ आमतौर पर एक वस्तु की त्वचा पर दिखाई देते हैं, और अंदर की तरफ इशारा करते हैं।"
markh44

हां, मुझे नहीं लगता कि सदस्य संदर्भों के संदर्भ में यह अच्छी सलाह है।
टिम एंगस

6

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

ऐसे मामलों में, असाइनमेंट ऑपरेटर (और अक्सर कॉपी कंस्ट्रक्टर) को गैर-उपयोग करने योग्य ( boost::noncopyableउन्हें निजी से विरासत में मिला या घोषित करके) बनाना सुनिश्चित करें।

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


6

जैसा कि सभी को लगता है कि मैं सामान्य नियम सौंप रहा हूं, मैं दो प्रस्ताव दूंगा:

  • कभी भी, कभी भी सदस्‍यों के रूप में उपयोग संदर्भों का उपयोग न करें। मैंने अपने कोड में कभी ऐसा नहीं किया है (सिवाय खुद को साबित करने के कि मैं इस नियम में सही था) और एक मामले की कल्पना नहीं कर सकता कि मैं ऐसा कहां करूंगा। शब्दार्थ बहुत भ्रामक हैं, और यह वास्तव में संदर्भ के लिए डिज़ाइन नहीं किए गए हैं।

  • हमेशा, हमेशा, प्रकारों के मापदंडों को पारित करते समय, मूल प्रकारों को छोड़कर, या जब एल्गोरिथ्म को एक प्रतिलिपि की आवश्यकता होती है, तो संदर्भ का उपयोग करें।

ये नियम सरल हैं, और मुझे अच्छी स्थिति में खड़ा किया है। मैं स्मार्ट पॉइंटर्स का उपयोग करने पर नियम बनाना छोड़ता हूं (लेकिन कृपया, ऑटो_प्रेट नहीं) दूसरों के वर्ग के सदस्यों के रूप में।


2
पहले एक पर बहुत सहमत नहीं हैं, लेकिन असहमति तर्क का मूल्य नहीं है। +1
डेविड रॉड्रिग्ज -

(हम एसओ के अच्छे मतदाताओं के साथ इस तर्क को खोते हुए प्रतीत होते हैं, हालांकि)
जेम्स हॉपकिन

2
मैंने नीचे मतदान किया क्योंकि "कभी भी, कभी भी वर्ग के सदस्यों के रूप में संदर्भों का उपयोग न करें" और निम्नलिखित औचित्य मेरे लिए सही नहीं है। जैसा कि मेरे उत्तर में समझाया गया है (और शीर्ष उत्तर पर टिप्पणी) और मेरे स्वयं के अनुभव से, ऐसे मामले हैं जहां यह केवल एक अच्छी बात है। मुझे लगता है कि आप की तरह जब तक मैं एक कंपनी में काम पर रखा गया था जहाँ वे इसे अच्छे तरीके से इस्तेमाल कर रहे थे और इसने मुझे यह स्पष्ट कर दिया कि ऐसे मामले हैं जहाँ यह मदद करता है। वास्तव में मुझे लगता है कि वास्तविक समस्या वाक्य रचना और छिपे हुए निहितार्थ के बारे में अधिक है जो संदर्भों का उपयोग करती है क्योंकि सदस्यों को प्रोग्रामर को यह समझने की आवश्यकता होती है कि वे क्या कर रहे हैं।
Klaim

1
नील> मैं सहमत हूं लेकिन यह "राय" नहीं है जिसने मुझे वोट दिया, यह "कभी नहीं" का दावा है। जैसा कि यहां बहस करना मददगार नहीं लगता, वैसे भी मैं अपना डाउन वोट रद्द कर दूंगा।
21'09

2
संदर्भ सदस्य शब्दार्थ भ्रमित कर रहे हैं के बारे में बताकर इस उत्तर को बेहतर बनाया जा सकता है। यह औचित्य महत्वपूर्ण है क्योंकि, इसके चेहरे पर, पॉइंटर्स अधिक शब्दार्थ से अस्पष्ट लगते हैं (उन्हें प्रारंभिक नहीं किया जा सकता है, और वे आपको अंतर्निहित वस्तु के स्वामित्व के बारे में कुछ भी नहीं बताते हैं)।
weberc2

4

हां: क्या यह कहना सही है कि संदर्भ वाली वस्तु को असाइन नहीं किया जाना चाहिए, क्योंकि किसी संदर्भ को एक बार आरम्भ करने के बाद नहीं बदला जाना चाहिए?

डेटा सदस्यों के लिए अंगूठे के मेरे नियम:

  • संदर्भ का उपयोग कभी न करें, क्योंकि यह असाइनमेंट को रोकता है
  • यदि आपकी कक्षा हटाने के लिए ज़िम्मेदार है, तो बूस्ट के scoped_ptr का उपयोग करें (जो कि auto_ptr से अधिक सुरक्षित है)
  • अन्यथा, पॉइंटर या कॉन्स्ट पॉइंटर का उपयोग करें

2
मैं एक मामले का नाम भी नहीं दे सकता जब मुझे व्यावसायिक वस्तु के असाइनमेंट की आवश्यकता होगी।
मायकोला गोलूबेव

1
+1: मैं बस Auto_ptr सदस्यों के साथ सावधान रहना चाहता हूँ - किसी भी वर्ग के पास जो उनके पास असाइनमेंट और कॉपी कंस्ट्रक्शन होना चाहिए, स्पष्ट रूप से परिभाषित किया गया है (उत्पन्न लोगों को इसकी आवश्यकता नहीं है)
जेम्स हॉपकिन

auto_ptr (समझदार) असाइनमेंट को भी रोकता है।

2
@ मायकोला: मैंने यह भी अनुभव किया कि मेरी 98% व्यावसायिक वस्तुओं को असाइनमेंट या कॉपी-कॉटर की आवश्यकता नहीं है। मैं इसे एक छोटे से मैक्रो द्वारा रोकता हूं जो मैं उन वर्गों के हेडर में जोड़ता हूं जो कॉपी करने वालों और ऑपरेटर () को बिना किसी कार्यान्वयन के निजी बनाता है। इसलिए 98% वस्तुओं में मैं संदर्भों का भी उपयोग करता हूं और यह सुरक्षित है।
mmmmmmmm

1
सदस्यों के रूप में संदर्भों का उपयोग यह स्पष्ट रूप से करने के लिए किया जा सकता है कि वर्ग के उदाहरण का जीवन अन्य वर्गों (या समान) के उदाहरणों के जीवन पर सीधे निर्भर है। "कभी भी एक संदर्भ का उपयोग न करें, क्योंकि यह असाइनमेंट को रोकता है" मान रहा है कि सभी वर्गों को असाइनमेंट की अनुमति है। यह मानते हुए कि सभी वर्गों के प्रति आपरेशन अनुमति देने के लिए है कि तरह है ...
Klaim

2

मैं आमतौर पर केवल सदस्य डेटा में एक पॉइंटर का उपयोग करता हूं जब पॉइंटर शून्य हो सकता है या बदल सकता है। क्या डेटा सदस्यों के संदर्भों पर संकेत पसंद करने के लिए कोई अन्य कारण हैं?

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


1
Lakos इसके लिए "लार्ज-स्केल C ++ सॉफ्टवेयर डिज़ाइन" में भी तर्क देता है।
जोहान कोटलिंस्की

मेरा मानना ​​है कि कोड कम्प्लीट इसकी भी वकालत करता है और मैं इसके खिलाफ नहीं हूं। हालांकि यह बहुत सम्मोहक नहीं है ...
markh44

2

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


0

अगर मैं प्रश्न को सही ढंग से समझूं ...

पॉइंटर के बजाय फ़ंक्शन पैरामीटर के रूप में संदर्भ: जैसा कि आपने बताया, एक पॉइंटर यह स्पष्ट नहीं करता है कि पॉइंटर की सफाई / आरंभीकरण का मालिक कौन है। जब आप पॉइंटर चाहते हैं तो एक साझा बिंदु को प्राथमिकता दें, यह C ++ 11 का एक हिस्सा है, और एक कमजोर_प्राथ जब डेटा की वैधता की गारंटी नहीं दी जाती है तो जीवनकाल के दौरान डेटा को इंगित करने वाले वर्ग को स्वीकार करना ;; C ++ 11. का एक हिस्सा भी एक फ़ंक्शन पैरामीटर के रूप में एक संदर्भ का उपयोग करके गारंटी देता है कि संदर्भ शून्य नहीं है। इसके आस-पास पाने के लिए आपको भाषा की विशेषताओं को तोड़ना होगा, और हम ढीले तोप कोडर्स की परवाह नहीं करेंगे।

संदर्भ आ सदस्य चर: डेटा वैधता के संबंध में ऊपर के रूप में। यह इंगित किए गए डेटा की गारंटी देता है, फिर संदर्भित है, मान्य है।

कोड में पहले की स्थिति में परिवर्तनशील वैधता की जिम्मेदारी न केवल बाद के कोड (आपके उदाहरण में वर्ग ए) को साफ करती है, बल्कि उपयोग करने वाले व्यक्ति को भी स्पष्ट करती है।

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

और बस के मामले में (जो कम संभावना वाला हूड है क्योंकि यह आपके कोड के संदर्भ में कोई मतलब नहीं होगा), एक अन्य विकल्प, एक गैर संदर्भित, गैर पॉइंटर ए पैरामीटर का उपयोग करने के लिए, ए की नकल करेगा, और प्रतिमान को बेकार बना देगा - मैं वास्तव में आपको नहीं लगता कि आप इसका मतलब एक विकल्प के रूप में समझते हैं।

इसके अलावा, यह भी गारंटी देता है कि आप संदर्भित डेटा को बदलने में सक्षम नहीं हैं, जहां एक पॉइंटर को संशोधित किया जा सकता है। एक कास्ट पॉइंटर तभी काम करेगा, जब डेटा के लिए संदर्भित / पॉइंटर परस्पर नहीं था।

यदि बी के लिए ए पैरामीटर सेट होने की गारंटी नहीं थी, या फिर से असाइन किया जा सकता है तो पॉइंटर्स उपयोगी होते हैं। और कभी-कभी एक कमजोर-सूचक केवल कार्यान्वयन के लिए बहुत ही क्रियात्मक होता है, और अच्छी संख्या में लोग या तो यह नहीं जानते हैं कि कमजोर_प्रति क्या है, या बस उन्हें नापसंद करते हैं।

इस उत्तर के अलावा आंसू, कृपया :)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.