जब संदर्भ बनाम पॉइंटर्स का उपयोग करना है


381

मैं संकेत बनाम संदर्भ के वाक्यविन्यास और सामान्य शब्दार्थ को समझता हूं, लेकिन मुझे यह कैसे तय करना चाहिए कि एपीआई में संदर्भ या संकेत का उपयोग करना अधिक या कम उपयुक्त है?

स्वाभाविक रूप से कुछ स्थितियों को एक या दूसरे की operator++आवश्यकता होती है ( संदर्भ तर्क की आवश्यकता होती है), लेकिन सामान्य तौर पर मुझे पता चल रहा है कि मैं पॉइंटर्स (और कॉन्स्ट पॉइंटर्स) का उपयोग करना पसंद करता हूं क्योंकि वाक्य रचना स्पष्ट है कि चर को विनाशकारी रूप से पारित किया जा रहा है।

निम्न कोड में जैसे:

void add_one(int& n) { n += 1; }
void add_one(int* const n) { *n += 1; }
int main() {
  int a = 0;
  add_one(a); // Not clear that a may be modified
  add_one(&a); // 'a' is clearly being passed destructively
}

सूचक के साथ, यह हमेशा (अधिक) स्पष्ट है कि क्या चल रहा है, इसलिए एपीआई के लिए और जैसे कि जहां स्पष्टता एक बड़ी चिंता है, संकेत संदर्भों से अधिक उपयुक्त नहीं हैं? क्या इसका मतलब यह है कि संदर्भ केवल तभी उपयोग किया जाना चाहिए जब आवश्यक हो (उदाहरण के लिए operator++)? क्या एक या दूसरे के साथ कोई प्रदर्शन चिंताएं हैं?

संपादित (बाहर):

NULL मान और कच्चे सरणियों के साथ काम करने की अनुमति देने के अलावा, ऐसा लगता है कि पसंद व्यक्तिगत पसंद के लिए नीचे आती है। मैंने Google के C ++ स्टाइल गाइड के संदर्भ में नीचे दिए गए उत्तर को स्वीकार कर लिया है , क्योंकि वे इस दृश्य को प्रस्तुत करते हैं कि "संदर्भ भ्रामक हो सकते हैं, क्योंकि उनके पास सिंटैक्स लेकिन पॉइंटर शब्दार्थ है।"

सूचक तर्कों को सैनिटाइज़ करने के लिए आवश्यक अतिरिक्त काम के कारण जो NULL नहीं होना चाहिए (जैसे add_one(0)कि रनटाइम के दौरान पॉइंटर संस्करण को कॉल करेगा और तोड़ देगा), यह संदर्भ क्षमता का उपयोग करने के लिए उन संदर्भों से समझ में आता है जहां एक ऑब्जेक्ट मौजूद होना चाहिए, हालांकि यह शर्म की बात है। वाक्यात्मक स्पष्टता खोने के लिए।


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

1
@ शेन्कोमस: पर्याप्त रूप से, मैं ज्यादातर TextMate का उपयोग करता हूं। फिर भी, मुझे लगता है कि यह बेहतर है कि अर्थ एक नज़र से स्पष्ट होगा।
conec

4
के बारे add_one(a);में स्पष्ट नहीं है कि क्या aसंशोधित होने जा रहा है? यह कोड में सही कहता है: एक जोड़ें
GManNickG

31
@connec: Google C ++ स्टाइल गाइड को एक अच्छा C ++ स्टाइल गाइड नहीं माना जाता है। यह Google के पुराने C ++ कोड बेस (यानी उनके सामान के लिए अच्छा) के साथ काम करने के लिए एक स्टाइल गाइड है। उस पर आधारित उत्तर को स्वीकार करने से कोई मदद नहीं मिल रही है। अपनी टिप्पणियों और स्पष्टीकरण को पढ़ते हुए आप पहले से ही निर्धारित राय के साथ इस सवाल पर आए थे और अपने दृष्टिकोण की पुष्टि करने के लिए अन्य लोगों की तलाश कर रहे हैं। परिणामस्वरूप आप प्रश्न को उत्तर दे रहे हैं और जो आप चाहते हैं / सुनने की अपेक्षा करते हैं, उसका उत्तर दें।
मार्टिन यॉर्क

1
यह केवल विधि के नामकरण द्वारा तय किया गया है addOneTo(...)। यदि आप ऐसा नहीं करना चाहते हैं, तो बस घोषणा को देखें।
स्टीफन

जवाबों:


296

जहाँ भी आप कर सकते हैं संदर्भ का उपयोग करें, जहाँ भी आपको इंगित करना चाहिए।

जब तक आप नहीं कर सकते तब तक संकेत से बचें।

कारण यह है कि संकेत किसी भी अन्य निर्माणों की तुलना में चीजों को पालन / पढ़ने, कम सुरक्षित और कहीं अधिक खतरनाक जोड़तोड़ करने के लिए कठिन बनाते हैं।

इसलिए अंगूठे का नियम केवल बिंदुओं का उपयोग करना है अगर कोई अन्य विकल्प नहीं है।

उदाहरण के लिए, किसी ऑब्जेक्ट को पॉइंटर वापस करना एक वैध विकल्प है जब फ़ंक्शन कुछ मामलों में नल्ट्रप्र वापस कर सकता है और यह मान रहा है कि यह इच्छा है। उस ने कहा, एक बेहतर विकल्प कुछ इसी तरह का उपयोग करना होगा boost::optional

एक अन्य उदाहरण विशिष्ट मेमोरी जोड़तोड़ के लिए रॉर्स मेमोरी का उपयोग करना है। यह पूरे कोड आधार के खतरनाक भागों को सीमित करने में मदद करने के लिए कोड के बहुत संकीर्ण हिस्सों में छिपा और स्थानीय होना चाहिए।

आपके उदाहरण में, सूचक को तर्क के रूप में उपयोग करने का कोई मतलब नहीं है क्योंकि:

  1. यदि आप nullptrतर्क के रूप में प्रदान करते हैं , तो आप अपरिभाषित व्यवहार-भूमि में जा रहे हैं;
  2. संदर्भ विशेषता संस्करण 1 के साथ समस्या को हल करने के लिए आसान नहीं है।
  3. संदर्भ विशेषता संस्करण उपयोगकर्ता के लिए समझने में सरल है: आपको एक वैध ऑब्जेक्ट प्रदान करना होगा, न कि कुछ ऐसा जो अशक्त हो सकता है।

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


49
मुझे यकीन नहीं है कि संकेत पढ़ने के लिए कुछ भी कठिन बनाते हैं? यह एक काफी सरल अवधारणा है और यह स्पष्ट करता है कि जब कुछ संशोधित होने की संभावना है। अगर कुछ भी कहूं तो यह पढ़ना मुश्किल है जब कोई संकेत नहीं हो रहा कि क्या हो रहा है, add_one(a)तो इसे संदर्भ द्वारा सेट करने के बजाय परिणाम क्यों नहीं लौटाना चाहिए ?
कनेक्शन

46
@connec: यदि add_one(a)भ्रामक है, तो ऐसा इसलिए है क्योंकि यह अनुचित रूप से नामित है। add_one(&a)एक ही भ्रम होगा, केवल अब आप सूचक को बढ़ा सकते हैं और वस्तु नहीं। add_one_inplace(a)सभी भ्रम से बचना होगा।
निकोल बोल

20
एक बिंदु, संदर्भ स्मृति को संदर्भित कर सकता है जो दूर जा सकते हैं जितनी आसानी से संकेत कर सकते हैं। इसलिए वे किसी भी संकेत की तुलना में सुरक्षित नहीं हैं। निरंतर और पासिंग रेफरेंस पॉइंटर्स की तरह खतरनाक हो सकते हैं।
डग टी।

6
@ मुझे लगता है कि कच्चे संकेत का मतलब था। मेरा मतलब था कि सी ++ में संकेत हैं, NULLऔर nullptr, और यह उनके पास एक कारण है। और यह कि "कभी पॉइंटर्स का उपयोग न करें", और / या "कभी NULL, हमेशा उपयोग न करें" देने के लिए एक अच्छी तरह से माना या यहां तक ​​कि यथार्थवादी सलाह नहीं है boost::optional। वह सिर्फ पागल है। मुझे गलत मत समझो, कच्चे पॉइंटर्स को C ++ की तुलना में C ++ में कम बार की आवश्यकता होती है, लेकिन फिर भी, वे उपयोगी हैं, वे "खतरनाक" नहीं हैं क्योंकि कुछ C ++ लोग दावा करना पसंद करते हैं (यह अतिशयोक्ति भी है), और फिर से: जब केवल एक पॉइंटर का उपयोग करना और return nullptr;एक लापता मूल्य को इंगित करना आसान होता है ... तो पूरे बूस्ट का आयात क्यों करें?

5
@ "NULL का उपयोग करना बुरा व्यवहार है" - अब यह केवल हास्यास्पद है। और ifअप्रचलित है और एक को while() { break; }इसके बजाय, सही का उपयोग करना चाहिए ? इसके अलावा, चिंता न करें, मैंने बड़े कोड बेस के साथ देखा और काम किया है, और हाँ, यदि आप लापरवाह हैं , तो स्वामित्व एक समस्या है। यदि आप सम्मेलनों से चिपके रहते हैं, तो उनका लगातार उपयोग करें और टिप्पणी करें और अपने कोड का दस्तावेज़ीकरण करें, हालाँकि। लेकिन आखिरकार, मुझे सी का उपयोग करना चाहिए क्योंकि मैं सी ++ के लिए बहुत गूंगा हूं, ठीक है?

62

प्रदर्शन बिल्कुल समान हैं, क्योंकि संदर्भ आंतरिक रूप से संकेत के रूप में कार्यान्वित किए जाते हैं। इस प्रकार आपको उस बारे में चिंता करने की आवश्यकता नहीं है।

संदर्भ और संकेत का उपयोग करने के बारे में आम तौर पर स्वीकार किए जाने वाले सम्मेलन नहीं हैं। कुछ मामलों में आपको संदर्भों (उदाहरण के लिए कॉपी कंस्ट्रक्टर) को वापस करना या स्वीकार करना होगा, लेकिन इसके अलावा आप अपनी इच्छानुसार ऐसा करने के लिए स्वतंत्र हैं। जब मैंने सामना किया है तो एक आम सम्मेलन में संदर्भ का उपयोग करना होता है जब पैरामीटर को एक मौजूदा ऑब्जेक्ट और पॉइंटर्स को संदर्भित करना चाहिए जब एक NULL मान ठीक है।

कुछ कोडिंग कन्वेंशन (जैसे Google के ) लिखते हैं कि व्यक्ति को हमेशा पॉइंटर्स, या कॉन्स्टेंस रेफ़रेंस का उपयोग करना चाहिए, क्योंकि संदर्भों में थोड़ा अस्पष्ट-वाक्यविन्यास होता है: उनके पास संदर्भ व्यवहार लेकिन मूल्य सिंटैक्स होता है।


10
बस इसमें थोड़ा सा जोड़ने के लिए, Google की शैली मार्गदर्शिका कहती है कि फ़ंक्शंस के लिए इनपुट पैरामीटर कॉन्स्टेंट रेफ़रेंस होने चाहिए और आउटपुट पॉइंटर्स होने चाहिए। मुझे यह पसंद है क्योंकि यह बहुत स्पष्ट करता है जब आप एक फ़ंक्शन हस्ताक्षर पढ़ते हैं कि इनपुट क्या है और आउटपुट क्या है।
Dan

44
@ डान: Google शैली गाइड Google के पुराने कोड के लिए है, और इसका उपयोग आधुनिक कोडिंग के लिए नहीं किया जाना चाहिए। वास्तव में, यह एक नई परियोजना के लिए एक बुरा कोडिंग शैली है।
GManNickG

13
@connec: मुझे इसे इस तरह से रखना चाहिए: अशक्त पूरी तरह से वैध सूचक मान है। कहीं भी एक सूचक है, मैं इसे मूल्य शून्य दे सकता हूं। के अपने दूसरे संस्करण Ergo add_oneहै टूट : add_one(0); // passing a perfectly valid pointer valuekaboom,। आपको यह जांचने की आवश्यकता है कि क्या यह अशक्त है। कुछ लोग मुंहतोड़ जवाब देंगे: "अच्छी तरह से मैं सिर्फ यह दस्तावेज करूंगा कि मेरा कार्य शून्य से काम नहीं करता है"। यह ठीक है, लेकिन फिर आप प्रश्न के उद्देश्य को पराजित करते हैं: यदि आप दस्तावेज को देखने जा रहे हैं तो यह देखने के लिए कि क्या यह ठीक है, आप फ़ंक्शन की घोषणा भी देखेंगे
GMANNICKG

8
यदि यह एक संदर्भ था तो आप देखेंगे कि ऐसा ही होना चाहिए। इस तरह के एक मुंहतोड़ बात याद आती है हालांकि: संदर्भ एक भाषा के स्तर पर लागू होता है कि यह एक मौजूदा वस्तु को संदर्भित करता है, और संभवत: अशक्त नहीं है, जबकि संकेत में ऐसा कोई प्रतिबंध नहीं है। मुझे लगता है कि यह स्पष्ट है कि भाषा-स्तरीय प्रवर्तन प्रलेखन-स्तरीय प्रवर्तन की तुलना में अधिक शक्तिशाली और कम त्रुटि वाला है। कुछ लोग यह कहकर मुंहतोड़ जवाब देने की कोशिश करेंगे: "देखो, अशक्त संदर्भ:। int& i = *((int*)0);यह एक वैध मुंहतोड़ जवाब नहीं है। पिछले कोड में मुद्दा सूचक उपयोग के साथ है, संदर्भ के साथ नहीं । संदर्भ कभी भी अशक्त, अवधि नहीं हैं।
GManNickG

12
नमस्कार, मैंने टिप्पणियों में भाषा के वकीलों की कमी देखी, इसलिए मुझे उपाय करने की आवश्यकता है: संदर्भ आमतौर पर संकेत द्वारा लागू किए जाते हैं, लेकिन मानक ऐसी कोई बात नहीं कहता है। कुछ अन्य तंत्र का उपयोग करते हुए एक कार्यान्वयन 100% शिकायत होगी।
थॉमस बोनिनी

34

से सी ++ पूछे जाने वाले प्रश्न लाइट -

जब आप कर सकते हैं तो संदर्भों का उपयोग करें और जब आपको करना हो तब इंगित करें।

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

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

नोट: पुरानी पंक्ति C प्रोग्रामर कभी-कभी संदर्भ पसंद नहीं करते हैं क्योंकि वे संदर्भ शब्दार्थ प्रदान करते हैं जो कॉलर के कोड में स्पष्ट नहीं है। कुछ सी ++ अनुभव के बाद, हालांकि, एक को जल्दी से पता चलता है कि यह सूचना छिपाने का एक रूप है, जो एक दायित्व के बजाय एक संपत्ति है। जैसे, प्रोग्रामर को मशीन की भाषा के बजाय समस्या की भाषा में कोड लिखना चाहिए।


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

1
@connec: निश्चित रूप से C प्रोग्रामर के पास यह उनकी भाषा के लिए सही है। लेकिन C ++ को C के रूप में मानने की गलती न करें। यह पूरी तरह से अलग भाषा है। यदि आप C ++ को C के रूप में मानते हैं, तो आप यह लिखते हैं कि C with classजो ( जैसे कि C ++ नहीं है) के रूप में संदर्भित है ।
मार्टिन यॉर्क

15

अंगूठे का मेरा नियम है:

  • आउटगोइंग या इन / आउट मापदंडों के लिए पॉइंटर्स का उपयोग करें। इसलिए यह देखा जा सकता है कि मूल्य में बदलाव होने जा रहा है। (आप का उपयोग करना चाहिए &)
  • पॉइंटर्स का उपयोग करें यदि NULL पैरामीटर स्वीकार्य मान है। (सुनिश्चित करें कि यह constएक आने वाला पैरामीटर है)
  • आने वाले पैरामीटर के लिए संदर्भों का उपयोग करें यदि यह NULL नहीं हो सकता है और एक आदिम प्रकार ( const T&) नहीं है।
  • नए बनाए गए ऑब्जेक्ट को वापस करते समय पॉइंटर्स या स्मार्ट पॉइंटर्स का उपयोग करें।
  • संदर्भों के बजाय संरचना या वर्ग के सदस्यों के रूप में संकेत या स्मार्ट पॉइंटर्स का उपयोग करें।
  • अलियासिंग के लिए संदर्भ का उपयोग करें (जैसे। int &current = someArray[i])

भले ही आप जो भी उपयोग करते हैं, अगर वे स्पष्ट नहीं हैं, तो अपने कार्यों और उनके मापदंडों के अर्थ को दस्तावेज करना न भूलें।


14

अस्वीकरण: इस तथ्य के अलावा कि संदर्भ NULL और न ही "रिबाउंड" नहीं हो सकता है (जिसका अर्थ है कि वे जिस वस्तु के उपनाम हैं उसे बदल नहीं सकते हैं), यह वास्तव में स्वाद के मामले में नीचे आता है, इसलिए मैं कहने वाला नहीं हूं "यह बेहतर है"।

उस ने कहा, मैं पोस्ट में आपके पिछले बयान से असहमत हूं, मुझे नहीं लगता कि कोड संदर्भों के साथ स्पष्टता खो देता है। आपके उदाहरण में,

add_one(&a);

से अधिक स्पष्ट हो सकता है

add_one(a);

चूँकि आप जानते हैं कि सबसे अधिक संभावना है कि मूल्य में बदलाव होने वाला है। हालांकि दूसरी ओर, समारोह के हस्ताक्षर

void add_one(int* const n);

कुछ हद तक स्पष्ट नहीं है: n एक पूर्णांक या एक सरणी होने जा रहा है? कभी-कभी आपके पास केवल (खराब प्रलेखित) हेडर तक पहुंच होती है, और हस्ताक्षर जैसे

foo(int* const a, int b);

पहली नजर में व्याख्या करना आसान नहीं है।

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


स्पष्ट प्रदर्शन के लिए धन्यवाद, जहां दोनों समाधान प्राप्त होते हैं और स्पष्टता खो देते हैं। मैं शुरुआत में पॉइंटर कैंप में था, लेकिन इससे बहुत फायदा होता है।
ज़ैक बेवोन-कॉलिन

12

दूसरों की तरह पहले से ही उत्तर: हमेशा उपयोग संदर्भ, जब तक चर जा रहा है NULL/ nullptrहै वास्तव में एक मान्य राज्य।

इस विषय पर जॉन कार्मैक का दृष्टिकोण समान है:

कम से कम हमारे कोड में NULL पॉइंटर्स सबसे बड़ी समस्या हैं। एक ध्वज और एक पते के रूप में एकल मूल्य का दोहरा उपयोग घातक मुद्दों की एक अविश्वसनीय संख्या का कारण बनता है। जब भी संभव हो सी + + संदर्भों पर पक्ष लिया जाना चाहिए; जबकि एक संदर्भ "वास्तव में" सिर्फ एक संकेतक है, इसमें न-नाल होने का निहित अनुबंध है। पूर्ण चेक करें जब पॉइंटर्स को संदर्भ में बदल दिया जाता है, तो आप उसके बाद के मुद्दे को अनदेखा कर सकते हैं।

http://www.altdevblogaday.com/2011/12/24/static-code-analysis/

2012-03-13 को संपादित करें

उपयोगकर्ता ब्रेट कुहन्स सही टिप्पणी करते हैं:

C ++ 11 मानक को अंतिम रूप दिया गया है। मुझे लगता है कि इस थ्रेड में यह उल्लेख करने का समय है कि अधिकांश कोड को संदर्भों के एक संयोजन, शेयर्ड_एप्ट्र और यूनीक_प्ट्र के साथ पूरी तरह से ठीक करना चाहिए।

यह सच है, लेकिन यह प्रश्न अभी भी बना हुआ है, यहां तक ​​कि स्मार्ट पॉइंटर्स के साथ कच्चे पॉइंटर्स की जगह भी।

उदाहरण के लिए, दोनों std::unique_ptrऔर std::shared_ptrउनके डिफ़ॉल्ट कंस्ट्रक्टर के माध्यम से "खाली" बिंदुओं के रूप में निर्मित किए जा सकते हैं:

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

और फिर, हमारे पास मनोरंजक समस्या है "हम फ़ंक्शन पैरामीटर के रूप में स्मार्ट पॉइंटर कैसे पास करते हैं?"

सवाल सी ++ के लिए जॉन का जवाब - बढ़ावा देने के लिए संदर्भों को साझा करना :: साझा_प्रति , और निम्नलिखित टिप्पणियां दर्शाती हैं कि फिर भी, कॉपी या संदर्भ द्वारा स्मार्ट पॉइंटर पारित करना उतना स्पष्ट नहीं है जितना कि कोई चाहेगा (मैं खुद का पक्ष लेता हूं) by-reference "डिफ़ॉल्ट रूप से, लेकिन मैं गलत हो सकता है)।


1
C ++ 11 मानक को अंतिम रूप दिया गया है। मुझे लगता है कि इस थ्रेड में यह उल्लेख करने का समय है कि अधिकांश कोड को संदर्भों के संयोजन के साथ पूरी तरह से ठीक करना चाहिए shared_ptr, और unique_ptr। स्वामित्व शब्दार्थ और इन / आउट पैरामीटर सम्मेलनों में इन तीन टुकड़ों और कॉन्स्टेंस के संयोजन का ध्यान रखा जाता है। सी + + में कच्चे पॉइंटर्स की कोई आवश्यकता नहीं है सिवाय जब विरासत कोड और बहुत अनुकूलित एल्गोरिदम के साथ काम करना। जिन क्षेत्रों में उनका उपयोग किया जाता है, उन्हें यथासंभव समझाया जाना चाहिए और किसी भी कच्चे पॉइंटर्स को शब्दार्थ रूप से उपयुक्त "आधुनिक" समकक्ष में बदलना चाहिए।
ब्रेट कुहन्स

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

@ पोवमान: मैं पूरी तरह से सहमत हूं: यदि स्वामित्व इंटरफ़ेस का हिस्सा नहीं है (और जब तक कि यह संशोधित नहीं होने वाला है, यह नहीं होना चाहिए), तो हमें एक पैरामीटर (या वापसी मान) के रूप में स्मार्ट पॉइंटर पास नहीं करना चाहिए। जब स्वामित्व इंटरफ़ेस का हिस्सा हो तो बात थोड़ी और जटिल हो जाती है। उदाहरण के लिए, सटर / मेयर्स एक अद्वितीय_प्रेटर को पैरामीटर के रूप में पास करने के बारे में बहस करते हैं: कॉपी (सटर) या आर-मूल्य संदर्भ (मेयर्स) द्वारा? एक एंटीपार्टर्न एक संकेतक को एक वैश्विक शेयर्ड_प्ट्र के आस-पास से गुजरने पर निर्भर करता है, उस पॉइंटर के अमान्य होने के जोखिम के साथ (समाधान स्टैक पर स्मार्ट पॉइंटर की नकल करता है)
9

7

यह स्वाद का मामला नहीं है। यहाँ कुछ निश्चित नियम हैं।

यदि आप उस दायरे के भीतर एक सांख्यिकीय रूप से घोषित चर को संदर्भित करना चाहते हैं जिसमें यह घोषित किया गया था तो C ++ संदर्भ का उपयोग करें, और यह पूरी तरह से सुरक्षित होगा। वही एक वैधानिक रूप से घोषित स्मार्ट पॉइंटर पर लागू होता है। संदर्भ द्वारा पैरामीटर पारित करना इस उपयोग का एक उदाहरण है।

यदि आप उस दायरे से कुछ भी संदर्भित करना चाहते हैं जो उस दायरे से व्यापक है जिसमें इसे घोषित किया गया है, तो आपको इसके लिए पूरी तरह से सुरक्षित होने के लिए संदर्भित स्मार्ट पॉइंटर का उपयोग करना चाहिए।

आप एक संग्रह के एक तत्व को सिंटैक्टिक सुविधा के संदर्भ के साथ संदर्भित कर सकते हैं, लेकिन यह सुरक्षित नहीं है; तत्व को कभी भी हटाया जा सकता है।

संग्रह के एक तत्व के लिए एक संदर्भ को सुरक्षित रूप से रखने के लिए, आपको एक संदर्भ गिने हुए स्मार्ट पॉइंटर का उपयोग करना होगा।


5

कोई भी प्रदर्शन अंतर इतना छोटा होगा कि यह उस दृष्टिकोण के उपयोग को उचित नहीं ठहराएगा जो कम स्पष्ट है।

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

किसी भी घटना में, मैं मूल रूप से आपके साथ सहमत हूं। मुझे उनके मूल्य को संशोधित करने के लिए संदर्भ लेने वाले फ़ंक्शन पसंद नहीं हैं, जब यह बहुत स्पष्ट नहीं है कि यह क्या कार्य कर रहा है। मैं भी उस स्थिति में पॉइंटर्स का उपयोग करना पसंद करता हूं।

जब आपको एक जटिल प्रकार में एक मूल्य वापस करने की आवश्यकता होती है, तो मैं संदर्भों को प्राथमिकता देता हूं। उदाहरण के लिए:

bool GetFooArray(array &foo); // my preference
bool GetFooArray(array *foo); // alternative

यहां, फ़ंक्शन नाम यह स्पष्ट करता है कि आपको किसी सरणी में जानकारी वापस मिल रही है। इसलिए कोई भ्रम नहीं है।

संदर्भों का मुख्य लाभ यह है कि वे हमेशा एक मान्य मान रखते हैं, पॉइंटर्स की तुलना में क्लीनर होते हैं, और किसी भी अतिरिक्त सिंटैक्स की आवश्यकता के बिना बहुरूपता का समर्थन करते हैं। यदि इनमें से कोई भी लाभ लागू नहीं होता है, तो पॉइंटर पर एक संदर्भ पसंद करने का कोई कारण नहीं है।


4

विकी से कॉपी किया गया -

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

मैं इसके साथ 100% सहमत हूं, और यही कारण है कि मेरा मानना ​​है कि आपको केवल एक संदर्भ का उपयोग करना चाहिए जब आपके पास ऐसा करने का बहुत अच्छा कारण हो।


मैं भी काफी हद तक सहमत हूं, हालांकि मैं इस बात पर विचार कर रहा हूं कि NULL पॉइंटर्स के खिलाफ अंतर्निहित सुरक्षा का नुकसान विशुद्ध रूप से वाक्यगत चिंताओं के लिए थोड़ा महंगा है, विशेष रूप से - हालांकि अधिक स्पष्ट - सूचक वाक्यविन्यास बहुत बदसूरत है वैसे भी।
conec

मुझे लगता है कि परिस्थिति एक महत्वपूर्ण कारक होगी। मुझे लगता है कि जब वर्तमान कोड आधार मुख्य रूप से पॉइंटर्स का उपयोग करता है तो यह एक बुरा विचार होगा, संदर्भ का उपयोग करने की कोशिश कर रहा है। यदि आप उनके संदर्भों की अपेक्षा करते हैं तो यह तथ्य कि उनका निहितार्थ शायद कम महत्वपूर्ण है ..
user606723

3

ध्यान में रखने के लिए अंक:

  1. संकेत हो सकते हैं NULL, संदर्भ नहीं हो सकते NULL

  2. संदर्भ का उपयोग करना आसान है, constएक संदर्भ के लिए इस्तेमाल किया जा सकता है जब हम मूल्य नहीं बदलना चाहते हैं और बस एक फ़ंक्शन में संदर्भ की आवश्यकता होती है।

  3. Pointer *थोड़ी देर के संदर्भ के साथ प्रयोग किया जाता है a &

  4. पॉइंटर अंकगणितीय ऑपरेशन की आवश्यकता होने पर पॉइंटर्स का उपयोग करें।

  5. आपके पास एक शून्य प्रकार के लिए संकेत हो सकते हैं, int a=5; void *p = &a;लेकिन एक शून्य प्रकार का संदर्भ नहीं हो सकता है।

सूचक बनाम संदर्भ

void fun(int *a)
{
    cout<<a<<'\n'; // address of a = 0x7fff79f83eac
    cout<<*a<<'\n'; // value at a = 5
    cout<<a+1<<'\n'; // address of a increment by 4 bytes(int) = 0x7fff79f83eb0
    cout<<*(a+1)<<'\n'; // value here is by default = 0
}
void fun(int &a)
{
    cout<<a<<'\n'; // reference of original a passed a = 5
}
int a=5;
fun(&a);
fun(a);

क्या उपयोग कब करना है इसका फैसला

सूचक : सरणी के लिए, लिंकलिस्ट, पेड़ कार्यान्वयन और सूचक अंकगणित।

संदर्भ : फ़ंक्शन मापदंडों और वापसी प्रकारों में।


2

" जहाँ भी संभव हो नियम का उपयोग करें " संदर्भ में समस्या है और यदि आप आगे उपयोग के लिए संदर्भ रखना चाहते हैं तो यह उत्पन्न होता है। उदाहरण के साथ यह स्पष्ट करने के लिए, कल्पना करें कि आपके पास निम्न वर्ग हैं।

class SimCard
{
    public:
        explicit SimCard(int id):
            m_id(id)
        {
        }

        int getId() const
        {
            return m_id;
        }

    private:
        int m_id;
};

class RefPhone
{
    public:
        explicit RefPhone(const SimCard & card):
            m_card(card)
        {
        }

        int getSimId()
        {
            return m_card.getId();
        }

    private:
        const SimCard & m_card;
};

पहले तो यह एक अच्छा विचार हो सकता RefPhone(const SimCard & card)है कि संदर्भ में पास किए गए कंस्ट्रक्टर में पैरामीटर हो , क्योंकि यह गलत / अशक्त बिंदु को कंस्ट्रक्टर से गुजरने से रोकता है। यह किसी तरह स्टैक पर चर के आवंटन को प्रोत्साहित करता है और RAII से लाभ उठाता है।

PtrPhone nullPhone(0);  //this will not happen that easily
SimCard * cardPtr = new SimCard(666);  //evil pointer
delete cardPtr;  //muahaha
PtrPhone uninitPhone(cardPtr);  //this will not happen that easily

लेकिन तब अस्थायी आपके खुशहाल दुनिया को नष्ट करने के लिए आते हैं।

RefPhone tempPhone(SimCard(666));   //evil temporary
//function referring to destroyed object
tempPhone.getSimId();    //this can happen

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

संपादित करें: ध्यान दें कि मैं नियम से जुड़ा था "जहाँ भी आप कर सकते हैं संदर्भ का उपयोग करें, जहाँ भी आपको इंगित करना चाहिए, तब तक संकेत से बचें जब तक आप नहीं कर सकते।" सबसे उत्कीर्ण और स्वीकृत उत्तर से (अन्य उत्तर भी ऐसा ही सुझाव देते हैं)। हालांकि यह स्पष्ट होना चाहिए, उदाहरण यह दिखाना नहीं है कि इस तरह के संदर्भ खराब हैं। हालांकि, उनका उपयोग बिंदुओं की तरह किया जा सकता है और वे कोड के लिए अपने स्वयं के खतरे ला सकते हैं।


संकेत और संदर्भ के बीच अंतर हैं।

  1. जब यह चर चर की बात आती है, तो संदर्भ दर्रा मान के द्वारा पास की तरह दिखता है, लेकिन सूचक शब्दार्थ (सूचक की तरह कार्य करता है) है।
  2. संदर्भ को 0 (नल) से सीधे आरंभीकृत नहीं किया जा सकता है।
  3. संदर्भ (संदर्भ, संदर्भित ऑब्जेक्ट) को संशोधित नहीं किया जा सकता है ("* कॉन्स्ट" सूचक के बराबर)।
  4. const संदर्भ अस्थायी पैरामीटर को स्वीकार कर सकता है।
  5. स्थानीय कास्ट संदर्भ अस्थायी वस्तुओं के जीवनकाल को लम्बा खींचता है

उन लोगों को ध्यान में रखते हुए मेरे वर्तमान नियम इस प्रकार हैं।

  • उन मापदंडों के लिए संदर्भों का उपयोग करें जो स्थानीय रूप से फ़ंक्शन दायरे में उपयोग किए जाएंगे।
  • पॉइंटर्स का उपयोग करें जब 0 (शून्य) स्वीकार्य पैरामीटर मान हो या आपको आगे उपयोग के लिए पैरामीटर को स्टोर करने की आवश्यकता हो। यदि 0 (शून्य) स्वीकार्य है, तो मैं पैरामीटर में "_n" प्रत्यय जोड़ रहा हूं, गार्डेड पॉइंटर (जैसे क्यूटी में QPointer) का उपयोग करें या बस इसे दस्तावेज करें। आप स्मार्ट पॉइंटर्स का भी उपयोग कर सकते हैं। आपको सामान्य पॉइंटर्स की तुलना में साझा किए गए पॉइंटर्स के साथ और भी अधिक सावधान रहना होगा (अन्यथा आप डिजाइन मेमोरी लीक और जिम्मेदारी की गड़बड़ी से समाप्त हो सकते हैं)।

3
आपके उदाहरण के साथ समस्या यह नहीं है कि संदर्भ असुरक्षित हैं, लेकिन यह कि आप अपने निजी सदस्यों को जीवित रखने के लिए अपने ऑब्जेक्ट उदाहरण के दायरे से बाहर कुछ पर भरोसा कर रहे हैं। const SimCard & m_card;बस एक बुरी तरह से लिखा कोड है।
plamenko

@plamenko मुझे डर है कि आप उदाहरण के उद्देश्य को नहीं समझते हैं। चाहे const SimCard & m_cardसही है या नहीं संदर्भ पर निर्भर करता। इस पोस्ट में संदेश यह नहीं है कि संदर्भ असुरक्षित हैं (यदि वे कठिन प्रयास करते हैं तो वे हो सकते हैं)। संदेश यह है कि आपको "जब भी संभव हो" मंत्रों का उपयोग करना चाहिए। उदाहरण "जब भी संभव हो संदर्भों का उपयोग करें" सिद्धांत के आक्रामक उपयोग का एक परिणाम है। यह स्पष्ट होना चाहिए।
दस्तावेज़

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

आपको व्यावहारिक रूप से सदस्यों की तरह कभी नहीं होना चाहिए const SimCard & m_card। यदि आप अस्थायी के साथ कुशल होना चाहते हैं, तो explicit RefPhone(const SimCard&& card)निर्माता जोड़ें ।
प्लैमेंको

@plamenko यदि आप कुछ बुनियादी समझ के साथ नहीं पढ़ सकते हैं, तो आपको मेरी पोस्ट से गुमराह होने की तुलना में बड़ी समस्या है। मुझे नहीं पता कि मैं और अधिक स्पष्ट कैसे हो सकता हूं। पहले वाक्य में देखिए। "जब भी संभव हो संदर्भों का उपयोग करें" मंत्र के साथ एक समस्या है! मेरे पोस्ट में आपने एक बयान कहाँ पाया है कि संदर्भ खराब हैं? मेरी पोस्ट के अंत में आपने लिखा है कि संदर्भों का उपयोग कहां करना है, इसलिए आप इस तरह के निष्कर्षों के साथ कैसे आए? यह सवाल का सीधा जवाब नहीं है?
डॉक

1

निम्नलिखित कुछ दिशानिर्देश हैं।

एक फ़ंक्शन इसे संशोधित किए बिना पास किए गए डेटा का उपयोग करता है:

  1. यदि डेटा ऑब्जेक्ट छोटा है, जैसे कि अंतर्निहित डेटा प्रकार या एक छोटी संरचना, तो इसे मान से पास करें।

  2. यदि डेटा ऑब्जेक्ट एक सरणी है, तो एक पॉइंटर का उपयोग करें क्योंकि यह आपकी एकमात्र पसंद है। कांस्टेबल को पॉइंटर बनाएं।

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

  4. यदि डेटा ऑब्जेक्ट एक क्लास ऑब्जेक्ट है, तो एक कॉन्स्ट रेफरेंस का उपयोग करें। क्लास डिज़ाइन के शब्दार्थ को अक्सर एक संदर्भ का उपयोग करने की आवश्यकता होती है, जो मुख्य कारण है C ++ ने यह सुविधा जोड़ी है। इस प्रकार, क्लास ऑब्जेक्ट लॉजिक को पास करने का मानक तरीका संदर्भ द्वारा है।

एक फ़ंक्शन कॉलिंग फ़ंक्शन में डेटा को संशोधित करता है:

1. यदि डेटा ऑब्जेक्ट एक अंतर्निहित डेटा प्रकार है, तो एक पॉइंटर का उपयोग करें। यदि आप फिक्स (& x) जैसे कोड को स्पॉट करते हैं, जहां x एक int है, तो यह बहुत स्पष्ट है कि यह फ़ंक्शन x को संशोधित करने का इरादा रखता है।

2. यदि डेटा ऑब्जेक्ट एक सरणी है, तो अपनी एकमात्र पसंद का उपयोग करें: एक पॉइंटर।

3. यदि डेटा ऑब्जेक्ट एक संरचना है, तो संदर्भ या पॉइंटर का उपयोग करें।

4. यदि डेटा ऑब्जेक्ट एक क्लास ऑब्जेक्ट है, तो एक संदर्भ का उपयोग करें।

बेशक, ये केवल दिशा-निर्देश हैं, और विभिन्न विकल्प बनाने के कारण हो सकते हैं। उदाहरण के लिए, सिनेमा बुनियादी प्रकारों के लिए संदर्भों का उपयोग करता है ताकि आप Cin >> & n के बजाय Cin >> n का उपयोग कर सकें।


0

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

int *pInt = new int; // allocates *pInt on the Heap

0

आपको ठीक से लिखा गया उदाहरण देखना चाहिए

void add_one(int& n) { n += 1; }
void add_one(int* const n)
{
  if (n)
    *n += 1;
}

इसीलिए यदि संभव हो तो संदर्भ बेहतर हैं ...


-1

बस अपना पैसा लगा रहे हैं। मैंने अभी एक परीक्षण किया है। उस पर एक छींक। मैं सिर्फ g ++ को संदर्भों का उपयोग करने की तुलना में पॉइंटर्स का उपयोग करके उसी मिनी-प्रोग्राम की असेंबली फ़ाइलों को बनाने देता हूं। आउटपुट को देखते समय वे बिल्कुल समान होते हैं। प्रतीक के अलावा अन्य। इसलिए प्रदर्शन (एक साधारण उदाहरण में) को देखते हुए कोई समस्या नहीं है।

अब बिंदु बनाम संदर्भ के विषय पर। IMHO मुझे लगता है कि स्पष्टता सबसे ऊपर है। जैसे ही मैं निहित व्यवहार पढ़ता हूं मेरे पैर की उंगलियां कर्ल होने लगती हैं। मैं मानता हूं कि यह अच्छा निहित व्यवहार है कि एक संदर्भ नहीं हो सकता है।

NULL पॉइंटर को डीफ़र करना समस्या नहीं है। यह आपके एप्लिकेशन को क्रैश कर देगा और डीबग करना आसान होगा। एक बड़ी समस्या गैर-मानकीकृत पॉइंटर्स हैं जिनमें अमान्य मान हैं। यह स्पष्ट रूप से एक स्पष्ट उत्पत्ति के बिना अपरिभाषित व्यवहार के कारण स्मृति भ्रष्टाचार का परिणाम होगा।

यह वह जगह है जहाँ मुझे लगता है कि संदर्भ संकेतकर्ताओं की तुलना में अधिक सुरक्षित हैं। और मैं एक पिछले बयान से सहमत हूं, कि इंटरफ़ेस (जिसे स्पष्ट रूप से प्रलेखित किया जाना चाहिए, अनुबंध द्वारा डिजाइन देखें, बर्ट्रेंड मेयर) एक फ़ंक्शन के मापदंडों का परिणाम निर्धारित करता है। अब इस सब को ध्यान में रखते हुए मेरी प्राथमिकताएँ जहाँ भी / जहाँ भी संभव हो संदर्भ का उपयोग करने के लिए जाती हैं।


-2

पॉइंटर्स के लिए, आपको उन्हें किसी चीज़ की ओर इशारा करने की ज़रूरत है, इसलिए पॉइंटर्स मेमोरी स्पेस की लागत लेते हैं।

उदाहरण के लिए एक पूर्णांक पॉइंटर लेने वाला फ़ंक्शन पूर्णांक चर नहीं लेगा। तो आपको उस फ़ंक्शन को पास करने के लिए पहले एक पॉइंटर बनाना होगा।

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


4
नहीं। एक फ़ंक्शन जो पॉइंटर लेता है, उसे पॉइंटर चर के आवंटन की आवश्यकता नहीं होती है: आप एक अस्थायी पास कर सकते हैं &address। एक संदर्भ निश्चित रूप से स्मृति को खर्च करेगा यदि यह एक वस्तु का सदस्य है, और इसके अलावा, सभी मौजूदा संकलक वास्तव में संदर्भ को पते के रूप में लागू करते हैं, इसलिए आप पैरामीटर-पासिंग या डीरफेरिंग के संदर्भ में कुछ भी नहीं बचाते हैं।
अंडरस्कोर_ड
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.