2012-03-05 27 views
5

के रूप में सूचक मुझे C++ linux में एक स्पष्टीकरण की आवश्यकता है।सदस्य के रूप में सूचक या सदस्य

मैं class C1 और एक अन्य class C2 है। C1 में C2 का संदर्भ होगा।

class C1 
{ 

    C2 &obj ; 

} 

मैं दो विकल्प यहाँ की सोच रहा हूँ,

  1. सीधे C2 &obj;
  2. C2 का सूचक बनाने के रूप में C2 के संदर्भ पकड़े, c2* obj;

कौन सा अच्छा है के रूप में? इसमें क्या अंतर है? जब या तो चुनते हैं?

+1

इसी तरह के प्रश्न http://stackoverflow.com/questions/892133/should-i-prefer-pointers-or-references-in-member-data –

उत्तर

3

बचें जितना संभव हो उतना एक संदर्भ सदस्य का उपयोग।

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

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

सबसे व्यावहारिक प्रयोजनों के लिए

(जब तक आप वास्तव में सी 2 आकार की वजह से उच्च स्मृति उपयोग के संबंध है) बस C1 के सदस्य, पर्याप्त होना चाहिए सूचक या संदर्भ सदस्य के बजाय के रूप में C2 का एक उदाहरण पकड़े, आप की एक पूरी बहुत बचत होती है कि अन्य समस्याओं के बारे में चिंता करना जो संदर्भ/सूचक सदस्य अतिरिक्त मेमोरी उपयोग के खर्च पर लाते हैं।

आप, एक सूचक का उपयोग करना चाहिए, तो आप एक कच्चे सूचक के बजाय एक स्मार्ट सूचक का उपयोग सुनिश्चित करें, जो आपके जीवन को ज्यादा संकेत के साथ आसान बना देगा।

+0

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

+0

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

0

एक सूचक संदर्भ दो मुख्य फायदे हैं। सूचक शून्य हो सकता है और एक सूचक को स्थानांतरित किया जा सकता है (उदाहरण के लिए ++ ऑपरेटर के साथ)। चलती आपको यहां मदद नहीं करती है। यदि आप कक्षा 1 को तत्काल करते समय आपकी कक्षा सी 2 ज्ञात नहीं है तो आपको एक पॉइंटर का उपयोग करना चाहिए क्योंकि आपके पास संदर्भ प्रारंभ करने का कोई तरीका नहीं है, लेकिन पॉइंटर को शून्य में प्रारंभ किया जा सकता है।

की तरह ए एल एस ने कहा, मैं भी संकेत दिए गए का उपयोग करते समय सी 2 उदाहरण बदल सकता है की सिफारिश करेंगे। आप इस मामले में संदर्भों का उपयोग कर सकते हैं लेकिन मुझे लगता है कि पॉइंटर्स एक 'क्लीनर' समाधान हैं।

+3

यह कोई लाभ नहीं है कि पॉइंटर्स को प्रारंभ करने की आवश्यकता नहीं है। – dangerousdave

0

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

ही एक मामला मैं जहां यह उचित है, के साथ आ सकते हैं, आप अजीब, बाहरी कचरा कलेक्टर कार्यक्षमता न किसी तरह का है।(उदाहरण के लिए सी ++ बिल्डर के स्वचालित आवंटन/ढेर पर वीसीएल घटकों का विलोपन।)

एक और मामला यह है कि यह वैध हो सकता है, जब आप सी ++ कक्षा के साथ सी संरचना को अनुकरण कर रहे हों, या जब एक निजी कक्षा के अंदर लिख रहे हों एक और कक्षा

लेकिन फिर संभवतः कक्षा के बाहर कुछ चीज़ों को इंगित करने की आवश्यकता त्रुटिपूर्ण प्रोग्राम डिज़ाइन से आती है। मुझे लगता है कि मेरे कोड को ऐसा करने की ज़रूरत क्यों है, और कम से कम पॉइंटर, यानी const *c2 const obj;

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

संपादित करें: क्यों यह बुरा व्यवहार अवधारणा private encapsulation कहा जाता है, जो प्रोग्राम डिजाइन object-oriented design बुलाया अवधारणा की आधारशिलाओं में से एक है है है के लिए तर्क।

+0

"वर्ग के बाहर कुछ चीज़ों को इंगित करने की आवश्यकता त्रुटिपूर्ण प्रोग्राम डिज़ाइन से आती है"। मैं दृढ़ता से असहमत हूं। –

+1

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

+0

@JamesKanze "ग्राफ" क्या है? इसका मतलब कुछ भी हो सकता है, हालांकि मुझे लगता है कि आप "एडीटी" नामक विशिष्ट एडीटी का मतलब है। उस उदाहरण के लिए, ग्राफ़ वर्ग के अंदर ग्राफ़ के सभी नोड्स (कोर्सेस) आवंटित किए जाने चाहिए। ग्राफ़ के निजी उप वर्ग के रूप में घोषित किए जाने पर नोड क्लास ग्राफ़ क्लास को पॉइंटर्स का पर्दाफाश कर सकता है। उपयोगकर्ता को खुद को कच्चे पॉइंटर्स से चिंता करने की आवश्यकता नहीं है, उन्हें सार्वजनिक सदस्य कार्यों के माध्यम से ग्राफ को नेविगेट करना चाहिए। – Lundin

0

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

उदाहरण के लिए, यदि आप किसी प्रकार की निर्भरता इंजेक्शन की आवश्यकता है तो आप संदर्भ सदस्य चर का उपयोग कर सकते हैं। फिर भी, आप पॉइंटर्स का उपयोग कर सकते हैं। हालांकि, ध्यान रखें कि संदर्भ सदस्यों के साथ कक्षाएं आम तौर पर गैर-प्रतिलिपि होनी चाहिए।

ज्यादातर मामलों में, आपको या तो पॉइंटर्स या वैल्यू सदस्य चर का उपयोग करना चाहिए।

+2

संदर्भ ऑब्जेक्ट को असाइन करने योग्य बनाते हैं, लेकिन इसे अभी भी कॉपी किया जा सकता है। (लेकिन मैं आपके मूल बिंदु से सहमत हूं: अधिकांश समय, कक्षा प्रकारों में संदर्भों के लिए पॉइंटर्स पसंद करते हैं। जब तक कि प्रकार पहले से ही गैर-लोकप्रिय नहीं है।) –

+0

@JamesKanze हां। अच्छी तरह से कहा गया। गैर-प्रतिलिपि के बारे में मेरा विचार यह है कि वर्ग को बढ़ावा देने से वंचित :: गैर-लोकप्रिय। उस स्थिति में यह गैर-असाइन करने योग्य भी है। लेकिन आपको वह बिंदु मिला जो मेरा कहना था –

संबंधित मुद्दे