2011-02-13 11 views

उत्तर

28

वहाँ पाँच मुख्य मामलों में जहां आप का उपयोग करना चाहिए रहे हैं पारित-दर-संदर्भ के ऊपर से गुजरती-दर-मूल्य:

  1. आप एक समारोह अपने तर्कों को संशोधित करने की जरूरत है कि कॉल कर रहे हैं, उपयोग पास-संदर्भ द्वारा इसकी एक ही रास्ता इस प्रभाव को प्राप्त करने के लिए के रूप में (मैं इलाज पारित-दर-संदर्भ और पारित-दर-सूचक इस मामले में दूसरे के स्थान पर, हालांकि पारित-दर-सूचक आप अक्सर स्पष्ट रूप से शून्य के लिए जाँच करने के लिए है के साथ)।
  2. आप एक समारोह एक पैरामीटर के रूप एक बड़ी वस्तु लेने के लिए, उस वस्तु की एक अनावश्यक प्रतिलिपि बनाने और एक बड़ी क्षमता हिट लेने से बचने के स्थिरांक संदर्भ द्वारा इसे पारित की जरूरत है कि कॉल कर रहे हैं।
  3. आप एक प्रति निर्माता जो परिभाषा के द्वारा एक संदर्भ रखना चाहिए लिख रहे हैं, संदर्भ द्वारा पास का उपयोग।
  4. यदि आप एक ऐसा फ़ंक्शन लिख रहे हैं जो पॉलिमॉर्फिक कक्षा पर काम करना चाहता है, तो संदर्भ के द्वारा पास का उपयोग करें या स्लाइसिंग से बचने के लिए पॉइंटर द्वारा पास करें।
  5. आप एक समारोह है कि एक बहुत बड़ी या uncopyable वस्तु वापस कर सकती है लिख रहे हैं, एक तरह से उत्पादित मूल्य स्टोर करने के लिए एक पैरामीटर का उपयोग करने के रूप में संदर्भ द्वारा पास का उपयोग।वर्ग नहीं है public कॉपी-निर्माता है, तो आप विकल्प नहीं है करता है

    :

+4

यदि संदर्भ में गुजरना # 1 पर है, तो आप एक पूर्ण तर्क नहीं चाहते हैं, इसलिए मैं बिल्कुल "अदला-बदली" – Marlon

+0

कारण 1 का उपयोग नहीं करता - कम से कम सुपरराइज के प्रिंसिपल का उल्लंघन है (जब संदर्भ के लिए संदर्भ पर लागू होता है पॉइंटर। कारण 2 encapsulation का उल्लंघन है। कारण 3, सही और विडंबना है - शेष वर्ग में संदर्भ अर्थशास्त्र द्वारा पारित होने से बचने के लिए मशीनरी को लागू करें। कारण 4 और 5 पॉइंटर संदर्भ से गुजरना पसंद करते हैं। –

+0

@ मार्लन- के लिए धन्यवाद यह इंगित करते हुए कि मैंने अपना जवाब अपडेट कर दिया है। जो भी कम हो गया है: क्या आप कृपया यह बता सकते हैं कि मैं यह उत्तर बेहतर बनाने के लिए क्या कर सकता हूं? – templatetypedef

7

कई चीजें हैं जिसमें शामिल हैं:,

प्रदर्शन

मूल्य प्रतियां डेटा द्वारा पासिंग तो मूल्य से बड़े डेटा संरचनाओं गुजर प्रदर्शन बाधित कर सकते हैं। संदर्भ द्वारा पास करने से डेटा में केवल एक संदर्भ (मूल रूप से पता) पास होता है। बड़े डेटा संरचनाओं के लिए, यह प्रदर्शन में काफी सुधार कर सकता है। छोटे डेटा संरचनाओं (एक int की तरह) के लिए, संदर्भ द्वारा गुजरने से प्रदर्शन को रोक सकता है।

संशोधन

मूल्य प्रतियां द्वारा पासिंग डेटा तो लक्ष्य कोड है कि नकल को संशोधित करता है, यह मूल प्रभावित नहीं करेगा। संदर्भ द्वारा उत्तीर्ण केवल डेटा का पता पास करता है, इसलिए उस संदर्भ के विरुद्ध किए गए संशोधन कॉलिंग कोड पर "दृश्यमान" होंगे।

+0

संदर्भ में छोटे डेटा संरचनाओं को 'int' अवरोध प्रदर्शन के रूप में क्यों पारित किया जाएगा? –

+0

@Kyle_the_hacker: संदर्भ की लोकैलिटी, मुझे कल्पना है। –

2

हां।

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

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

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

2

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

निम्नलिखित कार्यक्रम संकलन नहीं होगा:

class A 
{ 
public: 
    A(){} 
private: 
    A(const A&) {} 
}; 

//source of error : pass by value 
void f(A) {} 

int main() { 
     A a; 
     f(a); 
    return 0; 
} 

त्रुटि:

prog.cpp: In function ‘int main()’:
prog.cpp:10: error: ‘A::A(const A&)’ is private
prog.cpp:18: error: within this context
prog.cpp:18: error: initializing argument 1 of ‘void f(A)’

ideone पर अपने आप को देखें: http://www.ideone.com/b2WLi

लेकिन एक बार आप संदर्भ द्वारा समारोह f पास करते हैं, तो यह संकलित ठीक है: http://www.ideone.com/i6XXB

1

आपने अपने प्रश्न को सी और सी ++ दोनों के साथ टैग किया है।

इसलिए, मेरा सुझाव है कि आप सी ++ में संदर्भ द्वारा पास का उपयोग करने पर विचार करें जो इस सुविधा का समर्थन करता है और आप इसे सी में उपयोग करने पर विचार नहीं करते हैं जो इस सुविधा का समर्थन नहीं करता है।

-3

जबकि पॉइंटर्स संदर्भ हैं, सी ++ में "संदर्भ" आमतौर पर कुछ प्रकार & के पैरामीटर को टैग करने का अभ्यास संदर्भित करता है।

जो आपको कभी नहीं करना चाहिए। यह एकमात्र जगह है जो विभिन्न पूर्व परिभाषित ऑपरेटरों को लागू करने के लिए आवश्यक जादू वाक्यविन्यास के रूप में है। अन्यथा:

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

  • आपको संदर्भ द्वारा पैरामीटर में कभी भी पास नहीं करना चाहिए। फिर, इसका मतलब है कि आप मेटा ऑप्टिमाइज़ेशन कर रहे हैं। आपको हमेशा पास-दर-मूल्य होना चाहिए, अन्यथा आप किसी ऑब्जेक्ट के अंदर झुकने, इसके कार्यान्वयन की जांच करने और निर्णय लेने के लिए दोषी हैं कि कुछ कारणों से पास-बाय-रेफरेंस को प्राथमिकता दी जाती है।

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

+1

1) भले ही आप मूल्य से गुजरते हैं, आप फ़ंक्शन कॉल को देखकर उसे नहीं बता सकते हैं। 2) इसके बारे में कैसे। हमेशा संदर्भ द्वारा पास करें, जब तक आपको एक प्रतिलिपि की आवश्यकता न हो, अन्यथा आप किसी ऑब्जेक्ट के अंदर झुकने, इसके कार्यान्वयन की जांच करने और निर्णय लेने के लिए दोषी हैं कि कुछ कारणों से पास-बाय-वैल्यू को प्राथमिकता दी जाती है। –

+0

क्योंकि पास-बाय-वैल्यू किसी भी प्रोग्रामिंग भाषा का डिफ़ॉल्ट अर्थपूर्ण है जो फ़ंक्शन कॉल के संदर्भ में लिखा गया है। –

+1

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

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