2015-10-05 6 views
9

मैं वर्तमान में सी ++ प्राइमर से सी ++ सीख रहा हूं, और यह बताता है कि संदर्भ किसी अन्य चर नाम के लिए उपनाम है। यह भी बताता है कि एक पॉइंटर दूसरे चर को कैसे इंगित करता है। यह बताता है कि एक सूचक और संदर्भ के बीच का अंतर यह है कि पॉइंटर्स को फिर से सौंप दिया जा सकता है और संदर्भ नहीं हो सकते हैं।एक कॉन्स पॉइंटर (कॉन्स के लिए पॉइंटर नहीं) और संदर्भ के बीच कार्यात्मक अंतर क्या है?

निम्नलिखित कोड उदाहरण में, मैं सूचक या संदर्भ के साथ क्या कर सकता हूं जिसे मैं दूसरे के साथ नहीं कर सकता?

double pi = 3.14; 
double &piRef = pi; 
double *const piPnt = π 

//both of these examples are valid and do the same thing 
piRef = 3.14159; 
*piPnt = 3.14159; 

//however, if I attempt to reassign what the pointer points to, it is illegal. 
//this is the same as with a reference, as a reference can't be reassigned either 
double tau = 6.28; 
piPnt = τ 

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

+0

@juanchopanza मेरे उदाहरण में सूचक एक कॉन्स पॉइंटर है, इसलिए इसे फिर से असाइन नहीं किया जा सकता है। – john01dav

+0

लेकिन आप संदर्भ पर असाइनमेंट का उपयोग कर सकते हैं। बस याद रखें कि यह किसी और चीज के लिए उपनाम है। – juanchopanza

+0

@juanchopanza मैं सूचक पॉइंट के मूल्य को पुन: असाइन कर सकता हूं। उदाहरण के लिए, 'piRef = 3.14159' और '* piPnt = 3.14169' दोनों मान्य होंगे। एक पॉइंटर एक कॉन्स ऑब्जेक्ट को इंगित किए बिना स्थिर हो सकता है। – john01dav

उत्तर

5

व्यू पॉइंटर्स और संदर्भों के एक कार्यात्मक बिंदु से वास्तव में वही बात है ... वे किसी ऑब्जेक्ट का संदर्भ देते हैं और उस ऑब्जेक्ट की प्रति नहीं हैं।

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

आप तकनीकी रूप से किसी ऐसे संदर्भ के साथ समाप्त हो सकते हैं जो किसी ऑब्जेक्ट का संदर्भ नहीं दे रहा है (उदाहरण के लिए *p एक संदर्भ की अपेक्षा करने वाले फ़ंक्शन में p शून्य सूचक है) लेकिन यह "अपरिभाषित व्यवहार" है।

दूसरे शब्दों संकेत में अधिक "लचीला" संदर्भ से कर रहे हैं और इस संकलक

  • अनदेखी करने के लिए एक संदर्भ वस्तु यह
  • संदर्भित है एक संदर्भ कोई वस्तु
हो सकता है यही कारण है कि बदल सकते हैं यही कारण है कि अनुमति देता है

और कुछ मामलों में यह तेजी से कोड उत्पन्न कर सकता है।

रिबाइंडिंग की अतिरिक्त लचीलापन और NULL एस के लिए भुगतान करने के लिए "कीमत" यह है कि वाक्यविन्यास (कुछ हद तक gratuitously) अधिक परेशान है।

+1

किस मामले में मैं एक कॉन्स नल का उपयोग करना चाहता हूं सूचक? यदि इसका कोई उपयोग नहीं है, तो यह अस्तित्व में भी नहीं हो सकता है - यह निश्चित रूप से तब प्रासंगिक नहीं है। – john01dav

+0

आपकी दो स्थितियों का कहना है कि संकलक दो चीजों को अनदेखा कर सकता है, जहां तक ​​मुझे पता है कि अस्तित्व में नहीं है। एक संदर्भ एक गैर-ऑब्जेक्ट को इंगित नहीं कर सकता है और न ही यह संदर्भित कर सकता है कि यह क्या संदर्भित कर रहा है। – john01dav

+1

@ जॉन 01dav: बिल्कुल।सी ++ में ये चीजें असंभव हैं (एक वाक्य रचनात्मक और लागू संकलन समय, दूसरा क्योंकि यह असमर्थित और अपरिभाषित व्यवहार है) इसलिए संकलक कोड के मुकाबले बेहतर कोड उत्पन्न कर सकता है, यदि वे संभव हो तो उत्पन्न करना होगा। उदाहरण के लिए '++ x' फ़ंक्शन में कई बार बनाया गया है जहां' x' 'int' 'को संदर्भित पूर्णांक के पते को फिर से लोड करने की आवश्यकता नहीं है, जबकि' (* p) ++ 'जहां' p' एक सूचक है जो संकलक को यह भी मानना ​​चाहिए कि 'पी' बदल सकता था (संभवतः एलियासिंग के कारण भी)। – 6502

1

मैं पॉइंटर या संदर्भ के साथ क्या कर सकता हूं जो मैं अन्य के साथ नहीं कर सकता?

double *const piPnt = π 

ऊपर बयान

marks piPnt as a read only variable in memory layout 

तो, piPnt = &xyz अब एक त्रुटि फेंक होगा।

लेकिन सूचक बिंदु पर पते को बदलने के लिए अभी भी मान्य है।

है, *piPnt = 56 ठीक है।

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

संदर्भ के संबंध में अब

:

double &piRef = pi; 

आप सी ++ में एक संदर्भ reinitialize नहीं कर सकते। आप उस ऑब्जेक्ट को अलग-अलग मान निर्दिष्ट कर सकते हैं जो इसे संदर्भित करता है। यह हमेशा के लिए उस संदर्भ के लिए एक और एक ही वस्तु है। और यही वह है जो आपने अपने उदाहरण में किया था।

piRef = 3.14159; 

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

कुछ स्थानों पर जहां संदर्भ उपयोगी होते हैं:

  1. प्वाइंटर temporaries को इंगित नहीं कर सकते, मानक स्पष्ट रूप से यह कर मनाही। संदर्भ अस्थायी से बंध सकते हैं।
  2. एक पॉइंटर न्यूल हो सकता है जबकि एक संदर्भ हमेशा किसी ऑब्जेक्ट को संदर्भित करने के लिए माना जाता है। आप अभी भी एक संदर्भ लौटने वाले फ़ंक्शन से शून्य वापस कर सकते हैं, संकलक इसके बारे में शिकायत नहीं करेगा, लेकिन यह आत्मघाती है।
+0

आप बस एक कॉन्स पॉइंटर और एक संदर्भ और गैर-कॉन्स्ट पॉइंटर और संदर्भ के बीच अंतर के बीच समानताओं का जिक्र करते हैं। मैं एक कॉन्स्ट-पॉइंटर और संदर्भ के बीच मतभेदों की तलाश में हूं। – john01dav

+0

तदनुसार, इसे अभी संपादित करें। – basav

4

मैं सूचक या संदर्भ के साथ क्या कर सकता हूं जो मैं दूसरे के साथ नहीं कर सकता?

class X 
{ 
    // copy constructor 
    X(const X& a); 

    // move constructor 
    X(X&& a); 

    // copy assignment operator 
    X& operator=(const X& a); 

    // move assignment operator 
    X& operator=(X&& a); 
} 

(। दरअसल, ऑपरेटर ओवरलोडिंग गया था सी में संदर्भ शुरू ++ के लिए प्रेरित करने के उपयोग के मामले में)

क्या अक्सर अनदेखी कर रहा है:

संदर्भ आप कुछ निर्माणकर्ता और अधिभार ऑपरेटरों लिखने की अनुमति तथ्य यह है कि आधुनिक सी ++ X& (एक लाभा का संदर्भ) और X&& (एक रावल्यू का संदर्भ) के बीच अंतर करता है, लेकिन एक रैल्यू के सूचक के रूप में ऐसी कोई चीज़ नहीं है।

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