फंक्शन पैरामीटर: कॉपी या पॉइंटर?

मैं सी ++ के लिए नया हूं और कुछ सवाल हैं, यह उनमें से एक है।

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

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

0

6 उत्तर

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

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

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

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

In order to get reference semantics you can choose either passing by reference or by pointer, as others already said references are more natural than pointers in C++ (you don't have to use the address of operator &) and the only real advantage of pointers is if you want to enable NULL values.

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

0
जोड़ा

पॉइंटर का उपयोग करने से बचें। निरंतर संदर्भ का उपयोग करें यदि पैरामीटर में है तो बस IN आउट पैरामीटर के लिए संदर्भ

0
जोड़ा

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

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

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

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

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

0
जोड़ा

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

0
जोड़ा
गैर-0 नल पॉइंटर्स क्या हैं?
जोड़ा लेखक Motti, स्रोत
यही कारण है कि मैं नल पॉइंटर्स के लिए परीक्षण नहीं कर रहा हूं (जब तक कि यह न कहें कि फ़ंक्शन शून्य हो सकता है)। शून्य सूचक वैश्विक "अमान्य सूचक" समस्या का बहुत छोटा सबसेट है। हम 1 के लिए उदाहरण की जांच क्यों नहीं करते हैं 0 के रूप में स्पष्ट रूप से अमान्य होगा (कुछ अपवादों के साथ जहां 0 भी वैध है) ...
जोड़ा लेखक Ilya, स्रोत
मैं जोड़ूंगा कि गैर-0 नल पॉइंटर्स और भी परेशान हैं।
जोड़ा लेखक tloach, स्रोत
अन्यथा जंगली पॉइंटर्स के रूप में जाना जाता है
जोड़ा लेखक Mark Kegel, स्रोत
int * ohoh = नया int; ओह हटाओ; cout << ओह;//गैर-0 शून्य सूचक
जोड़ा लेखक MattyT, स्रोत

a reference is more common, or a const reference if they aren't going to change.

0
जोड़ा

ऐसे कई तरीके हैं जिनमें एक प्रति उत्तीर्ण करने से एक प्रतिलिपि सस्ता हो सकती है।

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

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

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

0
जोड़ा