2008-11-04 11 views
8

मैं सी ++ के लिए नया हूं और कुछ प्रश्न हैं, यह उनमें से एक है।फ़ंक्शन पैरामीटर: कॉपी या पॉइंटर?

क्या कोई कारण है जब आप एक या कई पैरामीटर में एक फ़ंक्शन का उपयोग कर रहे हैं, जिसके पैरामीटर आपको हमेशा कॉल कॉल से पहले एक चर में संग्रहीत किया जाएगा, चर की प्रतिलिपि पास करने के बजाय चर के लिए सूचक?

मैं प्रदर्शन के मामले में बात कर रहा हूं। मुझे लगता है कि यह सिर्फ एक सूचक (4 बाइट्स) की तुलना में पूरी संरचना की एक प्रति पास करने के लिए बहुत अधिक संसाधन लेगा।

उत्तर

1

एक संदर्भ अधिक आम है, या एक संदर्भ संदर्भ अगर वे बदलने के लिए नहीं जा रहे हैं।

4

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

+0

मैं जोड़ता हूं कि गैर-0 नल पॉइंटर्स और भी परेशान हैं। – tloach

+0

गैर-0 शून्य पॉइंटर्स क्या हैं? – Motti

+0

int * ohoh = new int; ओह हटाएं; cout << ओह; // गैर-0 शून्य सूचक – MattyT

2

मुख्य प्रश्न प्रदर्शन के बारे में नहीं है, लेकिन अर्थशास्त्र, और क्या आपका कार्य संरचना में डेटा को संशोधित करता है।

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

यदि आपका फ़ंक्शन संरचना को संशोधित नहीं करता है, तो मानों की प्रतिलिपि बनाने का कोई कारण नहीं है, क्योंकि उन्हें केवल पढ़ा जाएगा।

यदि आप संरचनाओं को पास करने वाले पॉइंटर्स की अवधारणा से सहज नहीं हैं, तो आपको कुछ अभ्यास करना चाहिए, क्योंकि यह सी और सी ++ में संरचनाओं से निपटने का एक सामान्य तरीका है।

जहां तक ​​प्रदर्शन चलता है, संरचना की प्रतिलिपि बनाने के लिए यह और अधिक काम है, लेकिन यह चीजों की योजना में काफी मामूली है। पहले अपने कोड के अर्थशास्त्र पर अपना ध्यान रखें।

4

pointer.Use निरंतर संदर्भ अगर प्रयोग करने से बचें किसी और बस में बाहर पैरामीटर के लिए संदर्भ

12

ऐसे कई तरीके हैं, जिसमें एक प्रति गुजर एक सूचक गुजर की तुलना में सस्ता हो सकता है पैरामीटर में है।

  1. ऑब्जेक्ट पॉइंटर से बराबर या छोटा है। एक मूल्य तक सीधे पहुंचने से सूचक को डीफरेंस करने से हमेशा तेज होगा।
  2. संरचना संकलक द्वारा ढेर पर पर्याप्त छोटा है। इस मामले में, संरचना में मूल्यों तक पहुंच अप्रत्यक्ष, अनुक्रमित एड्रेसिंग मोड के बजाय अनुक्रमित एड्रेसिंग मोड द्वारा की जाती है। पूर्व आमतौर पर तेज़ होते हैं।

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

अब उत्तर के हिस्से के लिए आप शायद यह नहीं सुनना चाहते हैं: यह आम तौर पर इतना अंतर नहीं बनाता है!पैरामीटर पासिंग विधि का प्रयोग करें जो आपके प्रोग्राम के अर्थशास्त्र के लिए सबसे अधिक समझ में आता है। यदि आपको बाद में पता चलता है कि किसी विशेष क्षेत्र में प्रदर्शन बाधा है तो प्रदर्शन में सुधार करने पर ध्यान केंद्रित करें। अनुकूलन खत्म मत करो!

10

पॉइंटर (या संदर्भ) द्वारा ऑब्जेक्ट पास करना और उसी ऑब्जेक्ट की एक प्रति को पास करना अलग-अलग अर्थशास्त्र है। यदि आप फ़ंक्शन कॉल के बाहर किसी ऑब्जेक्ट पर प्रतिबिंबित होने वाले परिवर्तनों को चाहते हैं, तो आप संदर्भ अर्थशास्त्र चाहते हैं, अन्यथा आप मूल्य semantics चाहते हैं।

आमतौर पर मूल्य अर्थ विज्ञान या तो मान द्वारा मूल्य पारित करके या स्थिरांक संदर्भ

void value_semantics(my_obj obj); 
void value_semantics(const my_obj& obj); 

हालांकि स्थिरांक संदर्भ तरीके के रूप में अच्छी तरह से कुछ कमियां द्वारा व्यक्त किया जा सकता है, यह कई अनुकूलन नहीं है जो संकलक की वजह से हो सकता है रोकता है aliasing issues तुच्छ रचनाकारों के साथ वस्तुओं के लिए भी संकेत का अतिरिक्त स्तर (एक संदर्भ एक सूचक के रूप में लागू किया जाता है) प्रतिलिपि से बचने के लाभों से अधिक हो सकता है।

संदर्भ अर्थशास्त्र प्राप्त करने के लिए आप या तो संदर्भ या पॉइंटर द्वारा पारित कर सकते हैं, क्योंकि अन्य पहले से ही कहा गया है कि संदर्भ सी ++ में पॉइंटर्स से अधिक प्राकृतिक हैं (आपको ऑपरेटर & के पते का उपयोग करने की आवश्यकता नहीं है) और केवल पॉइंटर्स का वास्तविक लाभ यह है कि यदि आप नल मान सक्षम करना चाहते हैं।

अंगूठे का नियम यह है कि गैर-तुच्छ कक्षाओं के लिए आपको कॉन्स संदर्भ द्वारा पारित किया जाना चाहिए, अन्यथा मूल्य से।