C ++ में फ़ंक्शन को ऑब्जेक्ट कैसे पास करें?


249

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

क्या मुझे संकेत, संदर्भ या गैर-सूचक और गैर-संदर्भ मान पास करने की आवश्यकता है? मुझे याद है कि जावा में इस तरह के मुद्दे नहीं हैं क्योंकि हम वस्तुओं के संदर्भ में सिर्फ चर को पास करते हैं।

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


6
आप किस पुस्तक से C ++ सीख रहे हैं?

17
उस पुस्तक की दृढ़ता से अनुशंसा नहीं की जाती है। स्टेन लिपमैन द्वारा C ++ प्राइमर के लिए जाएं।
प्रसून सौरव

23
खैर, आपकी समस्या है। Schildt मूल रूप से cr * p है - Koenig & Moo द्वारा त्वरित C ​​++ प्राप्त करें।

9
मुझे आश्चर्य है कि कैसे किसी ने बजरने स्ट्रॉस्ट्रुप द्वारा सी ++ प्रोग्रामिंग लैंग्वेज का उल्लेख नहीं किया। Bjarne Stroustrup C ++ का निर्माता है। C ++ सीखने के लिए एक बहुत अच्छी पुस्तक।
जॉर्ज

15
@ जॉर्ज: टीसी ++ पीएल शुरुआती के लिए नहीं है, लेकिन इसे सी ++ के लिए बाइबिल माना जाता है । एक्सडी
प्रसून सौरव

जवाबों:


277

C ++ 11 के लिए अंगूठे के नियम :

जब मान को छोड़कर, पास करें

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

सूचक द्वारा पासिंग की सलाह दी जाती है। वैकल्पिक मापदंडों को सर्वोत्तम रूप से std::optional( boost::optionalपुराने एसटीएल के लिए) के रूप में व्यक्त किया जाता है , और अलियासिंग को संदर्भ द्वारा ठीक किया जाता है।

C ++ 11 के चाल शब्दार्थ, जटिल वस्तुओं के लिए भी अधिक आकर्षक मूल्य से गुजरते और लौटते हैं।


C ++ 03 के लिए अंगूठे के नियम :

कब, को छोड़कर, संदर्भ द्वाराconst तर्क पास करें

  1. उन्हें फ़ंक्शन के अंदर बदला जाना चाहिए और ऐसे बदलावों को बाहर प्रतिबिंबित किया जाना चाहिए, जिस स्थिति में आप गैर- constसंदर्भ से गुजरते हैं
  2. फ़ंक्शन को किसी भी तर्क के बिना कॉल करने योग्य होना चाहिए, जिस स्थिति में आप पॉइंटर से गुजरते हैं, ताकि उपयोगकर्ता NULL/ 0/ के nullptrबजाय पारित कर सकें ; पिछले नियम को यह निर्धारित करने के लिए लागू करें कि क्या आपको एक संकेतक को एक तर्क से पारित करना चाहिएconst
  3. वे बिल्ट-इन प्रकार के होते हैं, जिन्हें कॉपी करके पास किया जा सकता है
  4. उन्हें फ़ंक्शन के अंदर बदला जाना चाहिए और इस तरह के बदलावों को बाहर परिलक्षित नहीं किया जाना चाहिए , जिस स्थिति में आप कॉपी से पास कर सकते हैं (एक विकल्प यह होगा कि पिछले नियमों के अनुसार पास हो और फ़ंक्शन के अंदर कॉपी बनाएं)

(यहां, "पास बाय वैल्यू" को "पास बाय कॉपी" कहा जाता है, क्योंकि वैल्यू से गुजरना हमेशा C ++ 03 में कॉपी बनता है)


इसमें और भी बहुत कुछ है, लेकिन ये कुछ शुरुआती नियम आपको काफी दूर तक ले जाएंगे।


17
+1 - मैं यह भी नोट करूंगा कि कुछ (यानी Google) को लगता है कि फ़ंक्शन के भीतर बदली जाने वाली वस्तुओं को नॉन-कॉस्ट संदर्भ के बजाय एक पॉइंटर के माध्यम से पारित किया जाना चाहिए। तर्क यह है कि जब किसी वस्तु का पता किसी फ़ंक्शन को दिया जाता है तो यह अधिक स्पष्ट होता है कि कहा गया फ़ंक्शन इसे बदल सकता है। उदाहरण: संदर्भ के साथ, कॉल फू (बार) है; क्या संदर्भ कॉस्ट है या नहीं, एक पॉइंटर के साथ यह फू (और बार) है; और अधिक स्पष्ट है कि फू एक उत्परिवर्तनीय वस्तु को पारित किया जा रहा है।
आरसी।

19
@ आरसी फिर भी आपको यह नहीं बताता है कि पॉइंटर कांस्टेबल है या नहीं। Google के दिशा-निर्देश विभिन्न C ++ ऑनलाइन समुदायों में बहुत सारे फ्लैक के लिए आए हैं - सिर्फ इसलिए, IMHO।

14
हालांकि अन्य संदर्भों में, गूगल जिस तरह से अग्रणी हो सकता है, सी ++ में उनकी शैली गाइड वास्तव में अच्छी नहीं है।
डेविड रॉड्रिग्ज - dribeas

4
@ArunSaha: एक शुद्ध शैली गाइड के रूप में, स्ट्रॉस्ट्रुप में एक गाइड है जिसे एक एयरोस्पेस कंपनी के लिए विकसित किया गया था। मैंने Google गाइड के माध्यम से ब्राउज़ किया और कुछ कारणों से इसे पसंद नहीं किया। सटर और अलेक्जेंड्रेस्कु सी ++ कोडिंग मानक पढ़ने के लिए एक महान पुस्तक है और आप काफी अच्छी सलाह प्राप्त कर सकते हैं, लेकिन यह वास्तव में एक स्टाइल गाइड नहीं है । मुझे स्टाइल के लिए किसी भी स्वचालित चेकर का पता नहीं है , मनुष्यों और सामान्य ज्ञान के अलावा।
डेविड रॉड्रिग्ज -

3
@anon हालाँकि, आपको इस बात की गारंटी मिलती है कि यदि किसी सूचक के माध्यम से तर्क पारित नहीं किया जाता है, तो उसे बदला नहीं जाता है। यह काफी मूल्यवान IMHO है, अन्यथा जब किसी फ़ंक्शन में एक वैरिएबल का पता लगाने की कोशिश की जाती है, तो आपको यह निर्धारित करने के लिए सभी फ़ंक्शन के हेडर फ़ाइलों की जांच करनी होगी कि क्या यह निर्धारित करने के लिए पारित हो गया है। इस तरह, आपको केवल उन लोगों को देखना होगा जो इसे सूचक के माध्यम से पारित किया गया था।
स्मेहूद

107

C ++ और Java में कन्वेंशन को कॉल करने में कुछ अंतर हैं। C ++ में तकनीकी रूप से केवल दो सम्मेलन बोलते हैं: पास-बाय-वैल्यू और पास-बाय-रेफरेंस, कुछ साहित्य के साथ जिसमें तीसरा पास-बाय-पॉइंटर कन्वेंशन (जो वास्तव में एक पॉइंटर प्रकार का पास-बाय-वैल्यू है)। इसके शीर्ष पर, आप शब्दार्थ को बढ़ाते हुए, तर्क के प्रकार में const-ness जोड़ सकते हैं।

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

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

मान से गुजरें (और पास-दर-सूचक)

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

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

यह वह कन्वेंशन है जिसका उपयोग C में तब किया जाता है जब किसी फ़ंक्शन को बाहरी चर को संशोधित करने की आवश्यकता होती है, और संदर्भ प्रकारों के साथ जावा में उपयोग किए जाने वाले कन्वेंशन: संदर्भ की प्रतिलिपि बनाई जाती है, लेकिन संदर्भित ऑब्जेक्ट समान है: संदर्भ / पॉइंटर के परिवर्तन बाहर दिखाई नहीं दे रहे हैं फ़ंक्शन, लेकिन इंगित की गई मेमोरी में परिवर्तन होते हैं।

समीकरण में कास्ट जोड़ना

C ++ में आप विभिन्न स्तरों पर चर, बिंदुओं और संदर्भों को परिभाषित करते समय वस्तुओं को निरंतर-नेस असाइन कर सकते हैं। आप एक चर को स्थिर होने की घोषणा कर सकते हैं, आप एक निरंतर उदाहरण के लिए एक संदर्भ की घोषणा कर सकते हैं, और आप सभी बिंदुओं को निरंतर वस्तुओं, निरंतर बिंदुओं को उत्परिवर्तित वस्तुओं और निरंतर तत्वों के लिए निरंतर संकेत को परिभाषित कर सकते हैं। जावा में इसके विपरीत आप केवल निरंतर-नेस (अंतिम कीवर्ड) के एक स्तर को परिभाषित कर सकते हैं: चर (उदाहरण के लिए आदिम प्रकार, संदर्भ प्रकारों के लिए संदर्भ), लेकिन आप एक अपरिवर्तनीय तत्व के संदर्भ को परिभाषित नहीं कर सकते (जब तक कि वर्ग स्वयं नहीं है) अपरिवर्तनीय)।

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

अंगूठे का नियम

यह पालन करने के लिए कुछ बुनियादी नियम हैं:

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

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

पक्षीय लेख

C ++ और Java सन्दर्भों के बीच के अंतर को महत्व देना महत्वपूर्ण है। C ++ सन्दर्भ में, वस्तुगत रूप से वस्तु का उदाहरण है, न कि इसका उपयोग करने वाला। सबसे सरल उदाहरण एक स्वैप फ़ंक्शन लागू कर रहा है:

// C++
class Type; // defined somewhere before, with the appropriate operations
void swap( Type & a, Type & b ) {
   Type tmp = a;
   a = b;
   b = tmp;
}
int main() {
   Type a, b;
   Type old_a = a, old_b = b;
   swap( a, b );
   assert( a == old_b );
   assert( b == old_a ); 
}

ऊपर दिया गया स्वैप फ़ंक्शन संदर्भों के उपयोग के माध्यम से अपने दोनों तर्कों को बदल देता है। जावा में निकटतम कोड:

public class C {
   // ...
   public static void swap( C a, C b ) {
      C tmp = a;
      a = b;
      b = tmp;
   }
   public static void main( String args[] ) {
      C a = new C();
      C b = new C();
      C old_a = a;
      C old_b = b;
      swap( a, b ); 
      // a and b remain unchanged a==old_a, and b==old_b
   }
}

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


4
@ दाविद-कृतिग्युज-ड्रिबेय मैं अंगूठे के खंड के नियमों को पसंद करता हूं, विशेष रूप से "आदिम प्रकारों के लिए पास-दर-मूल्य को प्राथमिकता दें"
yadab

मेरे हिसाब से यह सवाल का बेहतर जवाब है।
unrealsoul007

22

विचार करने के लिए कई मामले हैं।

पैरामीटर संशोधित ("आउट" और "इन / आउट" पैरामीटर)

void modifies(T &param);
// vs
void modifies(T *param);

यह मामला ज्यादातर शैली के बारे में है: क्या आप चाहते हैं कि कोड कॉल (obj) या कॉल (& obj) जैसा दिखे ? हालांकि, दो बिंदु हैं जहां अंतर मायने रखता है: वैकल्पिक मामला, नीचे, और आप ऑपरेटरों को ओवरलोड करते समय एक संदर्भ का उपयोग करना चाहते हैं।

... और वैकल्पिक

void modifies(T *param=0);  // default value optional, too
// vs
void modifies();
void modifies(T &param);

पैरामीटर संशोधित नहीं किया गया

void uses(T const &param);
// vs
void uses(T param);

यह दिलचस्प मामला है। अंगूठे का नियम "कॉपी करने के लिए सस्ता" प्रकारों को मूल्य से पारित किया जाता है - ये आम तौर पर छोटे प्रकार के होते हैं (लेकिन हमेशा नहीं) - जबकि अन्य को कॉन्स्टेंस रेफरी द्वारा पारित किया जाता है। हालांकि, अगर आपको अपने फ़ंक्शन के बिना एक प्रतिलिपि बनाने की आवश्यकता है, तो आपको मूल्य से गुजरना चाहिए । (हां, यह कार्यान्वयन विस्तार का एक सा उजागर करता है। C'est le C ++ )

... और वैकल्पिक

void uses(T const *param=0);  // default value optional, too
// vs
void uses();
void uses(T const &param);  // or optional(T param)

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

मूल्य द्वारा कास्ट एक कार्यान्वयन विस्तार है

void f(T);
void f(T const);

ये घोषणाएँ वास्तव में एक ही कार्य हैं! मूल्य से गुजरते समय, कास्ट शुद्ध रूप से एक कार्यान्वयन विवरण है। कोशिश करके देखो:

void f(int);
void f(int const) { /* implements above function, not an overload */ }

typedef void NC(int);       // typedefing function types
typedef void C(int const);

NC *nc = &f;  // nc is a function pointer
C *c = nc;    // C and NC are identical types

3
+1 जब मैं constमूल्य से गुजर रहा हूं तो कार्यान्वयन होने के बारे में नहीं जानता था ।
बाल्की

20

मान से पास करें:

void func (vector v)

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

नकारात्मक पक्ष सीपीयू चक्र और अतिरिक्त मेमोरी है जो ऑब्जेक्ट को कॉपी करने के लिए खर्च किया जाता है।

संदर्भ द्वारा पास करें:

void func (const vector& v);

यह फ़ॉर्म नकल ओवरहेड को हटाते समय पास-दर-मूल्य व्यवहार का अनुकरण करता है। फ़ंक्शन को मूल ऑब्जेक्ट तक पढ़ने की सुविधा मिलती है, लेकिन इसके मूल्य को संशोधित नहीं कर सकता है।

नकारात्मक पक्ष थ्रेड सुरक्षा है: किसी अन्य थ्रेड द्वारा मूल ऑब्जेक्ट में किए गए कोई भी परिवर्तन फ़ंक्शन के अंदर दिखाई देगा, जबकि यह अभी भी निष्पादित हो रहा है।

गैर-कास्ट संदर्भ द्वारा पास:

void func (vector& v)

इसे तब उपयोग करें जब फ़ंक्शन को चर के लिए कुछ मान वापस लिखना होगा, जो अंततः कॉलर द्वारा उपयोग किया जाएगा।

कॉन्स्ट रेफरेंस केस की तरह, यह थ्रेड-सेफ नहीं है।

पास पॉइंटर पॉइंटर द्वारा:

void func (const vector* vp);

अलग-अलग सिंटैक्स को छोड़कर आमतौर पर कॉन्स्ट-रेफरेंस से गुजरता है, साथ ही यह तथ्य भी है कि कॉलिंग फ़ंक्शन यह इंगित करने के लिए NULL पॉइंटर पास कर सकता है कि पास करने के लिए कोई वैध डेटा नहीं है।

धागा-सुरक्षित नहीं।

नॉन-कास्ट पॉइंटर द्वारा पास:

void func (vector* vp);

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

void func (string* str, /* ... */) {
    if (str != NULL) {
        *str = some_value; // assign to *str only if it's non-null
    }
}

जैसे सभी संदर्भ / पॉइंटर से गुजरते हैं, थ्रेड-सेफ नहीं।


0

चूंकि किसी ने उल्लेख नहीं किया है कि मैं इसे जोड़ रहा हूं, जब आप किसी फ़ंक्शन को c ++ में किसी फ़ंक्शन को पास करते हैं, तो ऑब्जेक्ट की डिफ़ॉल्ट प्रतिलिपि निर्माता को कहा जाता है यदि आपके पास ऐसा नहीं है जो ऑब्जेक्ट का एक क्लोन बनाता है और फिर इसे विधि को पास करता है, तो जब आप ऑब्जेक्ट मानों को बदलते हैं जो मूल ऑब्जेक्ट के बजाय ऑब्जेक्ट की कॉपी पर प्रतिबिंबित करेगा, जो कि c ++ में समस्या है, इसलिए यदि आप सभी क्लास एट्रिब्यूटर्स को पॉइंटर्स बनाते हैं, तो कॉपी कंस्ट्रक्टर कॉपी करने वालों के पतों की कॉपी करेंगे पॉइंटर विशेषताएँ, इसलिए जब विधि ऑब्जेक्ट पर इनवोकेशन करती है जो पॉइंटर विशेषताओं पते में संग्रहीत मानों में हेरफेर करती है, तो परिवर्तन मूल ऑब्जेक्ट में भी प्रतिबिंबित होते हैं जो एक पैरामीटर के रूप में पारित किया जाता है, इसलिए यह एक ही जावा का व्यवहार कर सकता है लेकिन यह मत भूलो कि आपकी सभी कक्षा गुण बिंदु होने चाहिए, आपको बिंदुओं के मान भी बदलने चाहिए,कोड स्पष्टीकरण के साथ बहुत स्पष्ट हो जाएगा।

Class CPlusPlusJavaFunctionality {
    public:
       CPlusPlusJavaFunctionality(){
         attribute = new int;
         *attribute = value;
       }

       void setValue(int value){
           *attribute = value;
       }

       void getValue(){
          return *attribute;
       }

       ~ CPlusPlusJavaFuncitonality(){
          delete(attribute);
       }

    private:
       int *attribute;
}

void changeObjectAttribute(CPlusPlusJavaFunctionality obj, int value){
   int* prt = obj.attribute;
   *ptr = value;
}

int main(){

   CPlusPlusJavaFunctionality obj;

   obj.setValue(10);

   cout<< obj.getValue();  //output: 10

   changeObjectAttribute(obj, 15);

   cout<< obj.getValue();  //output: 15
}

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


-1

एक पैरामीटर के रूप में किसी फ़ंक्शन को ऑब्जेक्ट पास करने के तीन तरीके हैं:

  1. संदर्भ से गुजारें
  2. मूल्य से गुजारें
  3. पैरामीटर में निरंतर जोड़ना

निम्नलिखित उदाहरण के माध्यम से जाओ:

class Sample
{
public:
    int *ptr;
    int mVar;

    Sample(int i)
    {
        mVar = 4;
        ptr = new int(i);
    }

    ~Sample()
    {
        delete ptr;
    }

    void PrintVal()
    {
        cout << "The value of the pointer is " << *ptr << endl
             << "The value of the variable is " << mVar;
   }
};

void SomeFunc(Sample x)
{
cout << "Say i am in someFunc " << endl;
}


int main()
{

  Sample s1= 10;
  SomeFunc(s1);
  s1.PrintVal();
  char ch;
  cin >> ch;
}

आउटपुट:

कहो मैं
someFunc में हूं
। सूचक का मान -17891602 है चर का मान 4 है


केवल 2 विधियाँ हैं (पहले 2 जिसका आपने उल्लेख किया है)। कोई मतलब नहीं है कि "पैरामीटर में निरंतर गुजरने" से आपका क्या मतलब है
एमएम

-1

C ++ में कार्य करने के लिए एक तर्क / पैरामीटर पास करने के तरीके निम्नलिखित हैं।

1. मूल्य से।

// passing parameters by value . . .

void foo(int x) 
{
    x = 6;  
}

2. संदर्भ द्वारा।

// passing parameters by reference . . .

void foo(const int &x) // x is a const reference
{
    x = 6;  
}

// passing parameters by const reference . . .

void foo(const int &x) // x is a const reference
{
    x = 6;  // compile error: a const reference cannot have its value changed!
}

3. वस्तु द्वारा।

class abc
{
    display()
    {
        cout<<"Class abc";
    }
}


// pass object by value
void show(abc S)
{
    cout<<S.display();
}

// pass object by reference
void show(abc& S)
{
    cout<<S.display();
}

1
"ऑब्जेक्ट द्वारा पास" एक बात नहीं है। केवल मान से पास होता है, और संदर्भ से गुजरता है। आपका "केस 3" वास्तव में मान से पास का एक मामला और संदर्भ द्वारा पास का एक मामला दिखाता है।
MM
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.