2012-07-10 11 views
8

मैं सी ++ पूछे जाने वाले प्रश्न पढ़ रहा था - "8.6 - When should I use references, and when should I use pointers?" इस बयान और विशेष रूप से:सी ++ में कोई "पूर्ण संदर्भ" क्यों नहीं है?

उपयोग संदर्भ जब आप कर सकते हैं, और संकेत आप के लिए है जब। एक संदर्भ है कि एक वस्तु का उल्लेख नहीं करता -

...

अपवाद ऊपर करने के लिए जहां एक समारोह के पैरामीटर या वापसी मान एक "प्रहरी" संदर्भ की जरूरत है। यह आमतौर पर एक पॉइंटर लौटने/लेने के द्वारा किया जाता है, और नल पॉइंटर को यह विशेष महत्व देता है (संदर्भ हमेशा ऑब्जेक्ट्स को उपनाम करते हैं, न कि एक संदर्भित न्यूल पॉइंटर)।

जो मैंने देखा है, उससे "सेंटीनेल" संदर्भ की आवश्यकता वास्तव में अक्सर संदर्भों के बजाय पॉइंटर्स का उपयोग करने का कारण है। मैं क्या सोच रहा हूं: सी ++ में संदर्भों के लिए विशेष "पूर्ण मूल्य" क्यों नहीं है? ऐसा लगता है कि यह पॉइंटर्स को लगभग अनावश्यक बना देगा, जो कई समस्याओं का समाधान करेगा।

तो यह भाषा विनिर्देश का हिस्सा क्यों नहीं था?

संपादित करें:

मुझे यकीन है कि मेरे सवाल का स्पष्ट है नहीं कर रहा हूँ - मुझे लगता है मैं शून्य संदर्भों के बारे में litterally नहीं कह रहा हूँ। अक्सर मैं पढ़ता हूं कि सी ++ में "संदर्भ वस्तु है"। और, अधिकांश ओओपी भाषाओं में, ऑब्जेक्ट्स नल - पास्कल, सी #, जावा, जावास्क्रिप्ट, पीएचपी इत्यादि हो सकते हैं, इन सभी में आप someObject = null या someObject := nil कर सकते हैं। वास्तव में, पास्कल पॉइंटर्स का भी समर्थन करता है लेकिन अभी भी ऑब्जेक्ट्स को nil होने की अनुमति देता है, क्योंकि इसका उपयोग होता है। तो सी ++ किसी भी तरह का विशेष क्यों है और इसमें कोई ऑब्जेक्ट नहीं है? क्या यह सिर्फ एक अनदेखी या वास्तविक निर्णय था?

+1

प्रे कि कैसे संकेत की आवश्यकता को दूर होगा बता सकते हैं? –

+3

@nathanwhite क्योंकि संदर्भ पॉइंटर्स के लिए वाक्य रचनात्मक चीनी होंगे, संभवतः, जब भी पॉइंटर्स होते हैं तब भी इसका उपयोग किया जा सकता है। कौन सा, आईएमओ, संदर्भों के कुछ लाभों को पूरी तरह से हटा देगा। – hvd

+4

पढ़ें [क्यों सी दोनों संकेत और संदर्भ है ++ करता है?] (Http://www2.research.att.com/~bs/bs_faq2.html#pointers-and-references) और [सी ++: अशक्त संदर्भ] (http://stackoverflow.com/questions/4364536/c-null-reference)। –

उत्तर

13

क्योंकि एक संदर्भ अर्थ किया जाता है कि यह एक वैध स्मृति पता है कि कभी नहीं बदलता ओर इशारा करता है; यानी कि इसे संदर्भित करना सुरक्षित/परिभाषित है और इसलिए कोई पूर्ण जांच की आवश्यकता नहीं है। संदर्भ डिजाइन द्वारा पुन: असाइन नहीं किया जा सकता है।

जब आप var हो सकते हैं तो पॉइंटर का उपयोग करें और क्लाइंट कोड को उस मामले को संभालना होगा। जब आप वैध/प्रारंभिक स्मृति पते की गारंटी दे सकते हैं तो आप एक संदर्भ का उपयोग करते हैं।

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

आप एक अशक्त संदर्भ यह तो वाक्य रचना के अलावा एक सूचक को अलग नहीं है की अनुमति देते हैं (एक ही शून्य चेकों जगह लेने के लिए की आवश्यकता होगी।)

अद्यतन:

"और, में अधिकांश ओओपी भाषाएं, ऑब्जेक्ट्स नल - पास्कल, सी #, जावा, जावास्क्रिप्ट, पीएचपी इत्यादि हो सकती हैं [...] तो सी ++ किसी भी तरह का विशेष क्यों है और इसमें कोई ऑब्जेक्ट नहीं है? क्या यह सिर्फ एक अनदेखा या वास्तविक निर्णय था ?"

मुझे लगता है कि आप थोड़ा के बारे में इस। जावा और भ्रमित हैं सी # आदि का आभास दे सकता है" सरल वाक्य रचना के साथ शून्य वस्तुओं ", लेकिन इन वस्तु संदर्भ हैं और अधिक या कम एक सी की तरह ++ सूचक, जीसी इंस्ट्रूमेंटेशन और अपवाद फेंक। उन भाषाओं में यदि आप एक "अशक्त ऑब्जेक्ट" पर काम आप की तरह NullReferenceException (सी #) अपवाद के कुछ प्रकार मिल जाएगा। नरक, जावा में इसकी एक NullPointerException कहा जाता है।

आपके पास इससे पहले कि आप उन्हें सुरक्षित रूप से उपयोग कर सकें, null की जांच करें। जैसे C++ poi nters (अधिकांश प्रबंधित भाषाओं को छोड़कर, पॉइंटर्स को डिफ़ॉल्ट रूप से NULL में प्रारंभ किया जाता है, जबकि सी ++ में आमतौर पर प्रारंभिक पॉइंटर मान (अन्यथा अपरिभाषित/जो भी स्मृति पहले से मौजूद थी) को सेट करने की देखभाल करने के लिए आपके ऊपर निर्भर करता है)।

  • कैसे आप कृपया, शून्य जाँच जहां आवश्यक करने के लिए एक सादा सूचक का उपयोग करें:

    सी ++ दृश्य पसंद वर्बोज़ किया जा रहा है, और इसलिए बारे में है।

  • उन संदर्भों का उपयोग करें जिनमें एक कंपाइलर-लागू वैधता अर्थात्/बाधा है।
  • अपने स्वयं के स्मार्ट पॉइंटर्स को रोल करें जो बुककीपिंग करते हैं और जिस तरह से आप चाहते हैं उन्हें व्यवहार करते हैं।
  • शून्य पॉइंटर्स का उपयोग (सतर्कता से!) यदि आवश्यक हो तो स्मृति के एक प्रकार के ब्लॉक को संदर्भित करने के लिए।
+2

नाइट: एक शून्य सूचक और एक अनियंत्रित सूचक दो अलग-अलग चीजें हैं। एक अनियंत्रित सूचक का पता नहीं लगाया जा सकता है, कम से कम भरोसेमंद नहीं, क्योंकि यह किसी वैध वस्तु सहित कहीं भी इंगित कर सकता है। – hvd

+0

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

0

संदर्भ कुछ को संदर्भित करना चाहिए, इसलिए, शून्य संदर्भ उपलब्ध नहीं है।
सी कोई संदर्भ है और हम इस भाषा में केवल संकेत का उपयोग कर सकते हैं, इसलिए, इस सी भाषा के साथ संगतता

1

परिभाषा के आधार पर संदर्भ किसी अन्य चर या वस्तु से जुड़ा होना चाहिए। तो एक खाली या शून्य संदर्भ प्रकार अस्तित्व के उद्देश्य का उल्लंघन करता है।

तकनीकी रूप से इसका मतलब यह होगा कि आप शून्य संदर्भ के साथ शुरू करते हैं, फिर इसे किसी चर के लिए असाइन करें या बाद में किसी अन्य चर पर पुन: असाइन किया जा सकता है। यह बस इतना नहीं है कि किस संदर्भ के लिए बनाया गया था।

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

संदर्भ हमेशा एक प्रकार से बंधेगा, जो सूचक के साथ मामला नहीं है।

+0

पहले 2 पैराग्राफ सही हैं। आखिरी का मतलब नहीं है। – wandalen

+0

मुझे निश्चित रूप से दिमाग में उपयोग का मामला था जो यहां सही ढंग से विस्तारित हो सकता है या नहीं। लेकिन कोई विस्तार या यहां तक ​​कि राय के साथ टिप्पणी के ऊपर, केवल "अर्थ नहीं है" और भी बेकार है और कोई वज़न नहीं है – fayyazkl

6

कृपया पॉइंटर्स और संदर्भों के बीच मतभेदों पर नज़र डालें - जबकि मानक इसे छोड़ देता है कि संदर्भ कैसे कार्यान्वित किए जाते हैं, वे इस समय हमेशा पॉइंटर्स के रूप में लागू होते हैं।

जिसका अर्थ है कि उनके बीच मुख्य अंतर ए) अर्थशास्त्र बी) पॉइंटर्स को संशोधित किया जा सकता है c) पॉइंटर्स शून्य हो सकते हैं।

तो संक्षिप्त जवाब यह है कि यह उद्देश्य पर किया गया था। जब आप प्रोग्रामर के रूप में एक संदर्भ देखते हैं तो आपको पता होना चाहिए कि ए) वह संदर्भ पॉप्युलेट किया गया है b) यह नहीं बदलेगा (और सी) आप इसे उसी ऑब्जेक्टिक्स के साथ उसी ऑब्जेक्टिक्स के साथ उपयोग कर सकते हैं)।

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

संपादित करें:

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

+0

मैंने अपना प्रश्न अपडेट कर लिया है। आप कैसे समझाएंगे कि लगभग सभी ओओ भाषाएं 'शून्य' संदर्भों की अनुमति देती हैं, लेकिन सी ++ नहीं है? इन सभी अन्य भाषाओं में, आपको हमेशा NULL की जांच करने की आवश्यकता नहीं होती है, यह पूरी तरह से संदर्भ पर निर्भर करता है। –

+3

मुझे कई ओओ भाषाएं नहीं हैं, लेकिन जिन लोगों के लिए मैं करता हूं, मैं असहमत हूं। जावा में संदर्भ भी नहीं हैं, जावा में केवल पॉइंटर्स हैं (उदा। शून्य हो सकता है, जिसे संशोधित किया जा सकता है), हालांकि एक अलग वाक्यविन्यास के साथ। कारणों में से एक जावा संदर्भ नहीं है क्योंकि जावा भी ढेर चर (प्रकार में बनाया से कम) नहीं है - सब कुछ ढेर, हर चर, एक सूचक है इसलिए अशक्त हो सकता है, कोई ढेर स्मृति, कोई के लिए की जरूरत है संदर्भ। वही वीबीए के लिए जाता है। जैसा कि मुझे पता है उतनी ओओ भाषाएं हैं। – Cookie

+2

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

1

एक C++ संदर्भ भावना है कि ज्यादातर अन्य भाषाओं शब्द का उपयोग में एक संदर्भ नहीं है, यह ऊर्फ जैसा अधिक है। एक सी ++ संदर्भ का उपयोग करने से आपको "dereferencing" शामिल नहीं होता है, उसी तरह आप एक सूचक को अस्वीकार करते हैं; यह प्रभावी ढंग से है जो इसे सौंपा गया ऑब्जेक्ट है।

वहाँ वास्तव में एक अशक्त वस्तु उदाहरण के रूप में ऐसी कोई बात नहीं है, तो आप एक सी ++ संदर्भ में ऐसी कोई बात करने के लिए नहीं बना सकते। अन्य भाषाओं में एक शून्य संदर्भ एक सी ++ शून्य सूचक के बराबर है; इसमें वास्तव में कुछ भी शामिल नहीं है।

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

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