क्या C ++ में संदर्भ से गुजरने पर सूचक द्वारा पास करने के लाभ हैं?


225

C ++ में संदर्भ द्वारा पास करने पर सूचक द्वारा पास करने के क्या लाभ हैं?

हाल ही में, मैंने कई उदाहरण देखे हैं जो संदर्भ से गुजरने के बजाय संकेत द्वारा तर्क वितर्क को चुनते हैं। क्या ऐसा करने के फायदे हैं?

उदाहरण:

func(SPRITE *x);

की एक कॉल के साथ

func(&mySprite);

बनाम

func(SPRITE &x);

की एक कॉल के साथ

func(mySprite);

newएक सूचक और स्वामित्व के परिणामस्वरूप मुद्दों को बनाने के बारे में मत भूलना ।
मार्टिन यॉर्क

जवाबों:


216

एक सूचक एक पूर्ण पैरामीटर प्राप्त कर सकता है, एक संदर्भ पैरामीटर नहीं कर सकता। यदि कभी कोई ऐसा मौका आता है जिसे आप "नो ऑब्जेक्ट" पास करना चाहते हैं, तो एक संदर्भ के बजाय एक पॉइंटर का उपयोग करें।

इसके अलावा, पॉइंटर से गुजरने से आपको कॉल साइट पर स्पष्ट रूप से देखने की अनुमति मिलती है कि क्या वस्तु मूल्य से या संदर्भ से गुजरती है:

// Is mySprite passed by value or by reference?  You can't tell 
// without looking at the definition of func()
func(mySprite);

// func2 passes "by pointer" - no need to look up function definition
func2(&mySprite);

18
अधूरा जवाब। पॉइंटर्स का उपयोग अस्थायी / प्रचारित वस्तुओं के उपयोग को अधिकृत नहीं करेगा, और न ही स्टैक जैसी वस्तुओं के रूप में इंगित ऑब्जेक्ट का उपयोग। और यह सुझाव देगा कि तर्क NULL हो सकता है जब, अधिकांश समय, NULL मान को निषिद्ध किया जाना चाहिए। पूर्ण उत्तर के लिए litb का उत्तर पढ़ें।
10

दूसरा फंक्शन कॉल एनोटेट हुआ करता था func2 passes by reference। जब भी मैं सराहना करता हूं कि इसका मतलब था कि यह एक उच्च-स्तरीय परिप्रेक्ष्य से "संदर्भ से" गुजरता है, तो एक कोड-स्तर के दृष्टिकोण पर एक पॉइंटर पारित करके लागू किया जाता है, यह बहुत भ्रामक था (देखें stackoverflow.com/questions/13382356/… )।
को ऑर्बिट

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

क्या हमारे पास C में यह पासिंग रेफरेंस नहीं है? मैं कोडब्लॉक (mingw) नवीनतम संस्करण का उपयोग कर रहा हूं और इसमें C प्रोजेक्ट का चयन कर रहा हूं। अभी भी संदर्भ से गुजर रहा है (func (int & a)) काम करता है। या यह C99 या C11 में उपलब्ध है?
जॉन व्हीलॉक

1
@JonWheelock: नहीं, C में पास-पास संदर्भ नहीं है। func(int& a)मानक के किसी भी संस्करण में मान्य C नहीं है। आप शायद अपनी फ़ाइलों को C ++ दुर्घटना के रूप में संकलित कर रहे हैं।
एडम रोसेनफील्ड

245

सूचक द्वारा पास करना

  • कॉलर को पता -> पारदर्शी नहीं लेना है
  • मतलब के लिए एक 0 मूल्य प्रदान किया जा सकता है nothing। इसका उपयोग वैकल्पिक तर्क प्रदान करने के लिए किया जा सकता है।

संदर्भ से गुजारें

  • कॉलर सिर्फ ऑब्जेक्ट पास करता है -> पारदर्शी। ऑपरेटर ओवरलोडिंग के लिए उपयोग किया जाना है, क्योंकि सूचक प्रकारों के लिए ओवरलोडिंग संभव नहीं है (संकेत बिल्ट प्रकार हैं)। तो आप string s = &str1 + &str2;संकेत का उपयोग नहीं कर सकते ।
  • कोई 0 मान संभव नहीं -> कॉल किए गए फ़ंक्शन को उनके लिए जांचना नहीं है
  • Const का संदर्भ भी अस्थायीता स्वीकार करता है: void f(const T& t); ... f(T(a, b, c));पॉइंटर्स का उपयोग इस तरह नहीं किया जा सकता है क्योंकि आप अस्थायी का पता नहीं लगा सकते हैं।
  • अंतिम लेकिन कम से कम, संदर्भों का उपयोग करना आसान है -> बग के लिए कम मौका।

7
सूचक द्वारा पास करना भी 'स्वामित्व हस्तांतरित है या नहीं?' सवाल। संदर्भों में ऐसा नहीं है।
फ्राइरिच राबे

43
मैं "कीड़े के लिए कम मौका" से असहमत हूं। कॉल साइट का निरीक्षण करते समय और पाठक "फू (और एस)" देखता है, यह तुरंत स्पष्ट है कि एस संशोधित किया जा सकता है। जब आप "फू (ओं)" पढ़ते हैं, तो यह बिल्कुल स्पष्ट नहीं है कि क्या एस संशोधित किया जा सकता है। यह बग्स का एक प्रमुख स्रोत है। शायद कीड़े के एक निश्चित वर्ग की संभावना कम है, लेकिन कुल मिलाकर, संदर्भ से गुजरना बग का एक बड़ा स्रोत है।
विलियम पर्ससेल

25
"पारदर्शी" से आपका क्या तात्पर्य है?
Gbert90

2
@ Gbert90, यदि आप किसी कॉल साइट पर foo (& a) देखते हैं, तो आपको पता है कि foo () एक पॉइंटर प्रकार लेता है। यदि आप फू (ए) देखते हैं, तो आप नहीं जानते कि यह संदर्भ लेता है या नहीं।
माइकल जे। डेवनपोर्ट

3
@ MichaelJ.Davenport - अपने स्पष्टीकरण में, आप "पारदर्शी" सुझाव देते हैं कि "स्पष्ट है कि कॉलर एक पॉइंटर पास कर रहा है, लेकिन यह स्पष्ट नहीं है कि कॉलर एक संदर्भ से गुजर रहा है" की तर्ज पर कुछ मतलब है। जोहान्स की पोस्ट में, वे कहते हैं, "पासिंग बाई पॉइंटर - कॉलर को पता लेना है -> पारदर्शी नहीं" और "पास बाय रेफरेंस - कॉलर सिर्फ ऑब्जेक्ट पास करता है -> पारदर्शी" - जो आपके कहने के लगभग विपरीत है । मुझे लगता है कि Gbert90 का प्रश्न "पारदर्शी" से आपका क्या मतलब है?
हैप्पी ग्रीन किड नेप्स

66

मुझे "cplusplus.com:" के एक लेख द्वारा तर्क पसंद है

  1. मान द्वारा पास करें जब फ़ंक्शन पैरामीटर को संशोधित नहीं करना चाहता है और मूल्य (इन्टल्स, डबल्स, चार, बूल आदि) को कॉपी करना आसान है ... सरल प्रकार। std :: string, std :: वेक्टर, और अन्य सभी STL। कंटेनर सरल प्रकार नहीं हैं।)

  2. जब मूल्य कॉपी करने के लिए महंगा हो तो कॉन्स्ट पॉइंटर से पास करें और फ़ंक्शन इंगित किए गए मान को संशोधित नहीं करना चाहता है और NULL एक मान्य, अपेक्षित मान है जो फ़ंक्शन संभालता है।

  3. मान कॉपी करने के लिए महंगा होने पर नॉन-कास्ट पॉइंटर द्वारा पास करें और फ़ंक्शन इंगित किए गए मान को संशोधित करना चाहता है और NULL एक मान्य, अपेक्षित मान है जो फ़ंक्शन संभालता है।

  4. मान को कॉपी करने के लिए महंगा होने पर कॉन्स्ट रेफरेंस से पास करें और फ़ंक्शन AND NULL को भेजे गए मान को संशोधित नहीं करना चाहता है यदि इसके बजाय एक पॉइंटर का उपयोग किया गया था तो यह एक वैध मूल्य नहीं होगा।

  5. मान को कॉपी करने के लिए महंगा होने पर गैर-कॉन्टेस्ट संदर्भ द्वारा पास करें और फ़ंक्शन AND NULL को संदर्भित मूल्य को संशोधित करना चाहता है यदि एक पॉइंटर का उपयोग किया गया था, तो एक वैध मूल्य नहीं होगा।

  6. टेम्प्लेट फ़ंक्शंस लिखते समय, कोई स्पष्ट उत्तर नहीं है क्योंकि इस पर चर्चा करने के लिए कुछ ट्रेडऑफ़ हैं जो इस चर्चा के दायरे से परे हैं, लेकिन यह कहना पर्याप्त है कि अधिकांश टेम्प्लेट मान या मान (कॉन्स्ट) संदर्भ द्वारा अपने पैरामीटर लेते हैं हालाँकि, क्योंकि इटिअटर सिंटैक्स पॉइंटर्स ("डीरेफेरेंस" के लिए तारांकन चिह्न) के समान है, कोई भी टेम्प्लेट फ़ंक्शन, जो यह तर्क देता है कि तर्कों के रूप में डिफ़ॉल्ट रूप से स्वीकार किए गए पॉइंटर्स द्वारा भी होगा (और NULL के लिए जाँच नहीं है क्योंकि NULL पुनरावृत्ति अवधारणा का एक अलग सिंटैक्स है) )।

http://www.cplusplus.com/articles/z6vU7k9E/

मैं इससे क्या लेना चाहता हूं कि सूचक या संदर्भ पैरामीटर का उपयोग करने के लिए मुख्य अंतर यह है कि क्या NULL एक स्वीकार्य मूल्य है। बस।

क्या मूल्य इनपुट, आउटपुट, मोडिबल है आदि सभी के बाद फ़ंक्शन के बारे में प्रलेखन / टिप्पणियों में होना चाहिए।


हां, मेरे लिए NULL संबंधित शर्तें यहां मुख्य चिंताएं हैं। उद्धृत करने के लिए Thx ..
बाइनरीगुए

62

एलन होलब की "पर्याप्त रस्सी को अपने आप को गोली मारने के लिए" निम्नलिखित 2 नियमों को सूचीबद्ध करता है:

120. Reference arguments should always be `const`
121. Never use references as outputs, use pointers

वह कई कारणों को सूचीबद्ध करता है जिनके संदर्भ C ++ में जोड़े गए थे:

  • वे कॉपी कंस्ट्रक्टर को परिभाषित करने के लिए आवश्यक हैं
  • वे ऑपरेटर अधिभार के लिए आवश्यक हैं
  • const संदर्भ आपको एक कॉपी से बचने के दौरान पास-पास-मूल्य शब्दार्थ प्रदान करने की अनुमति देते हैं

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

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


8
उस तर्क में मेरा रुख यह है कि यदि फ़ंक्शन नाम डॉक्स की जाँच किए बिना, यह पूरी तरह से स्पष्ट कर देता है, कि परम को संशोधित किया जाएगा, तो एक गैर-कास्ट संदर्भ ठीक है। तो व्यक्तिगत रूप से मैं "getDetails (DetailStruct & result)" की अनुमति दूंगा। वहाँ एक पॉइंटर NULL इनपुट की बदसूरत संभावना को बढ़ाता है।
स्टीव जेसप 19

3
यह भ्रामक है। यहां तक ​​कि अगर कुछ संदर्भ पसंद नहीं करते हैं, तो वे भाषा का एक महत्वपूर्ण हिस्सा हैं और इसका उपयोग किया जाना चाहिए। तर्क करने की यह पंक्ति यह है कि आप किसी भी प्रकार के स्टोर करने के लिए टेंपलेट का उपयोग नहीं कर सकते हैं। जलाकर उत्तर पढ़ें।
डेविड रॉड्रिग्ज - drieaseas

4
मैं यह नहीं देखता कि यह कैसे भ्रामक है - ऐसे समय होते हैं जब संदर्भ की आवश्यकता होती है, और ऐसे समय होते हैं जब सर्वोत्तम प्रथाएं सुझाव दे सकती हैं कि आप भले ही उनका उपयोग न करें। वही भाषा की किसी भी विशेषता के लिए कहा जा सकता है - विरासत, गैर-सदस्य मित्र, ऑपरेटर अतिभार, एमआई, आदि ...
माइकल बूर

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

1
यह नियम google c ++ स्टाइल गाइड में प्रयोग किया जाता है: google-styleguide.googlecode.com/svn/trunk/…
एंटोन डेनेको

9

पूर्ववर्ती पदों के स्पष्टीकरण:


संदर्भ एक गैर-शून्य सूचक प्राप्त करने की गारंटी नहीं है। (हालांकि हम अक्सर उन्हें ऐसा मानते हैं।)

जबकि भयावह रूप से बुरा कोड, जैसा कि आप वुडशेड खराब कोड के पीछे ले जाते हैं , निम्नलिखित संकलन और चलाएगा: (कम से कम मेरे संकलक के तहत।)

bool test( int & a)
{
  return (&a) == (int *) NULL;
}

int
main()
{
  int * i = (int *)NULL;
  cout << ( test(*i) ) << endl;
};

मेरे पास संदर्भ के साथ वास्तविक मुद्दा अन्य प्रोग्रामर्स के साथ है, इसलिए आईडीआईओटीएस को कहा जाता है , जो कंस्ट्रक्टर में आवंटित करते हैं, विध्वंसक में निपटाते हैं, और कॉपी कंस्ट्रक्टर या ऑपरेटर = () की आपूर्ति करने में विफल होते हैं।

अचानक फू (बार बार) और फू (बार और बार) के बीच अंतर की दुनिया है । (स्वचालित बिटवाइज़ कॉपी ऑपरेशन हो जाता है। विध्वंसक में विक्षेपण दो बार हो जाता है।)

शुक्र है कि आधुनिक कंपाइलर समान पॉइंटर के इस दोहरे व्यवहार को उठाएंगे। 15 साल पहले, वे नहीं थे। (Gcc / g ++ के तहत, पुराने तरीकों को फिर से दिखाने के लिए setenv MALLOC_CHECK_ 0 का उपयोग करें ।) परिणाम, DEC UNIX के तहत, एक ही मेमोरी में दो अलग-अलग ऑब्जेक्ट्स को आवंटित किया जा रहा है। वहाँ मज़ा डिबगिंग के बहुत सारे ...


अधिक व्यावहारिक रूप से:

  • संदर्भ छिपाते हैं कि आप कहीं और संग्रहीत डेटा बदल रहे हैं।
  • कॉपिड ऑब्जेक्ट के साथ एक संदर्भ को भ्रमित करना आसान है।
  • संकेत यह स्पष्ट करते हैं!

16
यह फ़ंक्शन या संदर्भों की समस्या नहीं है। आप भाषा के नियम तोड़ रहे हैं। अपने आप से अशक्त सूचक को पहले से ही अपरिभाषित व्यवहार करना। "संदर्भ एक गैर-शून्य सूचक प्राप्त करने की गारंटी नहीं है।": मानक खुद कहते हैं कि वे हैं। अन्य तरीके अपरिभाषित व्यवहार का गठन करते हैं।
जोहान्स स्काउब -

1
मैं लिट से सहमत हूं। जबकि सच है, जो कोड आप हमें दिखा रहे हैं वह किसी और चीज की तुलना में अधिक तोड़फोड़ है। कुछ भी तोड़फोड़ करने के तरीके हैं, जिसमें "संदर्भ" और "सूचक" नोटेशन दोनों शामिल हैं।
10

1
मैंने कहा कि यह "आपको वुडशेड खराब कोड के पीछे ले गया है"! उसी नस में, आपके पास i = new FOO भी हो सकते हैं; हटाओ मैं; परीक्षण (* मैं); एक और (दुर्भाग्य से आम) झूलने वाला सूचक / संदर्भ घटना।
मिस्टर डे

1
यह वास्तव में नहीं है अपसंदर्भन शून्य यही समस्या है, बल्कि का उपयोग कि dereferenced (शून्य) वस्तु। जैसे, वास्तव में भाषा-कार्यान्वयन के दृष्टिकोण से संकेत और संदर्भ के बीच कोई अंतर (वाक्यविन्यास के अलावा) नहीं है। यह उन उपयोगकर्ताओं को है जिनके पास अलग-अलग अपेक्षाएं हैं।
श्री ऋ।

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

5

आशय व्यक्त करने के संदर्भ में, यहां अधिकांश उत्तर फ़ंक्शन हस्ताक्षर में कच्चे सूचक होने में निहित अस्पष्टता को संबोधित करने में विफल होते हैं। समस्याएं निम्नलिखित हैं:

  • कॉल करने वाले को यह नहीं पता होता है कि सूचक एकल ऑब्जेक्ट्स की ओर इशारा करता है, या वस्तुओं के "सरणी" की शुरुआत के लिए।

  • कॉल करने वाले को यह नहीं पता होता है कि सूचक उस मेमोरी को "मालिक" करता है या नहीं। IE, फ़ंक्शन स्मृति को मुक्त करना चाहिए या नहीं। ( foo(new int)- क्या यह मेमोरी लीक है?)।

  • कॉल करने वाले को यह नहीं पता है कि nullptrफ़ंक्शन में सुरक्षित रूप से पारित किया जा सकता है या नहीं ।

इन सभी समस्याओं को संदर्भ द्वारा हल किया जाता है:

  • संदर्भ हमेशा एक ही वस्तु को संदर्भित करते हैं।

  • संदर्भ कभी भी उनके द्वारा संदर्भित स्मृति के मालिक नहीं होते हैं, वे केवल स्मृति में एक दृश्य हैं।

  • संदर्भ शून्य नहीं हो सकते।

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

  • कोई स्पष्ट अप्रत्यक्ष नहीं। यह कच्चे पॉइंटर के साथ कोई समस्या नहीं है, क्योंकि हमें &ऑपरेटर को यह दिखाने के लिए उपयोग करना होगा कि हम वास्तव में एक पॉइंटर पास कर रहे हैं। उदाहरण के लिए, int a = 5; foo(a);यह यहाँ बिल्कुल स्पष्ट नहीं है कि संदर्भ द्वारा पारित किया जा रहा है और संशोधित किया जा सकता है।
  • Nullability। बिंदुओं की यह कमजोरी भी एक ताकत हो सकती है, जब हम वास्तव में चाहते हैं कि हमारे संदर्भ अशक्त हों। के रूप में देखकर std::optional<T&>मान्य नहीं है (अच्छे कारणों के लिए) संकेत हमें उस nullability आप चाहते हैं देना है।

तो ऐसा लगता है कि जब हम स्पष्ट अप्रत्यक्ष के साथ एक अशक्त संदर्भ चाहते हैं, तो हमें एक T*अधिकार के लिए पहुंचना चाहिए ? गलत!

कपोल-कल्पना

अशक्तता के लिए हमारी हताशा में, हम तक पहुँच सकते हैं T*, और बस पहले से सूचीबद्ध सभी कमियों और अर्थ अस्पष्टताओं को अनदेखा कर सकते हैं । इसके बजाय, हमें सी ++ के लिए सबसे अच्छा काम करना चाहिए: एक अमूर्त। यदि हम बस एक वर्ग लिखते हैं जो एक पॉइंटर के चारों ओर घूमता है, तो हम अभिव्यंजकता प्राप्त करते हैं, साथ ही अशक्तता और स्पष्ट अप्रत्यक्षता भी।

template <typename T>
struct optional_ref {
  optional_ref() : ptr(nullptr) {}
  optional_ref(T* t) : ptr(t) {}
  optional_ref(std::nullptr_t) : ptr(nullptr) {}

  T& get() const {
    return *ptr;
  }

  explicit operator bool() const {
    return bool(ptr);
  }

private:
  T* ptr;
};

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

void foo(optional_ref<int> x) {
  if (x) {
    auto y = x.get();
    // use y here
  }
}

int x = 5;
foo(&x); // explicit indirection here
foo(nullptr); // nullability

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

  • इंटरफ़ेस स्पष्ट रूप से दिखाता है कि संदर्भ केवल एक वस्तु को संदर्भित करना चाहिए।
  • स्पष्ट रूप से यह उस मेमोरी का मालिक नहीं है जिसका वह उल्लेख करता है, क्योंकि इसमें कोई उपयोगकर्ता परिभाषित डिस्ट्रक्टर नहीं है और मेमोरी को हटाने की कोई विधि नहीं है।
  • कॉलर जानता है nullptrकि पारित किया जा सकता है, क्योंकि फ़ंक्शन लेखक स्पष्ट रूप से एक के लिए पूछ रहा हैoptional_ref

हम इंटरफ़ेस को यहाँ से और अधिक जटिल बना सकते हैं, जैसे कि समानता ऑपरेटर, एक मोनैडिक get_orऔर mapइंटरफ़ेस जोड़ना , एक ऐसा तरीका जो मूल्य प्राप्त करता है या एक अपवाद, constexprसमर्थन को फेंकता है । जो आपके द्वारा किया जा सकता है।

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


3

ज़रुरी नहीं। आंतरिक रूप से, संदर्भ द्वारा पास करना संदर्भित ऑब्जेक्ट के पते को अनिवार्य रूप से पास करके किया जाता है। तो, वहाँ वास्तव में कोई दक्षता हासिल करने के लिए एक सूचक पारित करके नहीं थे।

संदर्भ से गुजरने से एक लाभ होता है। आपको गारंटी दी जाती है कि जो भी वस्तु / प्रकार पास किया जा रहा है उसका एक उदाहरण है। यदि आप एक पॉइंटर में पास होते हैं, तो आप NULL पॉइंटर प्राप्त करने का जोखिम चलाते हैं। पास-दर-संदर्भ का उपयोग करके, आप अपने फ़ंक्शन के कॉल करने वाले को एक स्तर की अनुमानित NULL-जाँच कर रहे हैं।


1
यह एक फायदा और नुकसान दोनों है। बहुत से API कुछ उपयोगी होने के मतलब के लिए NULL पॉइंटर्स का उपयोग करते हैं (यानी NULL timespec हमेशा के लिए प्रतीक्षा करते हैं, जबकि मूल्य का मतलब है कि लंबे समय तक प्रतीक्षा करें)।
ग्रेग रोजर्स

1
@ ब्रायन: मैं नाइट-पिकिंग नहीं बनना चाहता, लेकिन मैं यह नहीं कहूंगा कि किसी को एक संदर्भ प्राप्त करने के लिए एक उदाहरण प्राप्त करने की गारंटी है। यदि किसी फ़ंक्शन का कॉलर डैन्गलिंग पॉइंटर को संदर्भित करता है, जिसे कैलली नहीं जान सकती है, तो डैंग्लिंग संदर्भ अभी भी संभव है।
१aid:

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

जिन प्रोग्रामों में झूलने के संदर्भ हैं, वे मान्य नहीं हैं C ++। इसलिए, हां, कोड मान सकता है कि सभी संदर्भ वैध हैं।
कोनराड रुडोल्फ

2
मैं निश्चित रूप से एक अशक्त सूचक को हटा सकता हूं और संकलक यह बताने में सक्षम नहीं होगा ... यदि संकलक यह नहीं बता सकता है कि यह "अमान्य सी ++" है, तो क्या यह वास्तव में अमान्य है?
rmeador
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.