दिलचस्प पोस्ट
HttpUrlConnection के साथ प्रीपेडिव बेसिक एथ? वेब स्क्रैपिंग शिष्टाचार इकाई फ़्रेमवर्क और बिजनेस ऑब्जेक्ट्स सवेइवस्टाइनस्टेट () और रीस्टोरइनस्टास्टस्टेट () पर कैसे उपयोग करें? लिनक में संयोजन जेनरेटर सी ++ सिंगलटन डिजाइन पैटर्न आईओएस 10 समर्थन के साथ Xcode 7.3.1 बड़ी फ़ाइलों के साथ Git वाई-फाई के बजाय एंड्रॉइड एप्लिकेशन में 3 जी कनेक्शन का उपयोग कैसे करें? जावास्क्रिप्ट का उपयोग करके विशिष्ट देरी के बाद स्क्रिप्ट निष्पादित करें मौजूदा डेटाबेस से asp.net MVC5 पहचान प्रमाणन कैसे जोड़ना मैं CoffeeScript के लिए Rails 3.1 में "-bare" विकल्प का उपयोग कैसे कर सकता हूं? एंड्रॉइड – लॉगकेट संदेशों की अधिकतम लंबाई निर्धारित करें स्प्रिंग-डाटा-जेपीए एनोटेशन के लिए setMaxResults? प्राइमफेस को दबाए जाने पर घटनाओं का निष्पादन आदेश p: कमांड बटन

सी ++ में कार्य करने के लिए ऑब्जेक्ट कैसे पास करें?

मैं सी ++ प्रोग्रामिंग के लिए नया हूँ, लेकिन मुझे जावा में अनुभव है सी ++ में कार्य करने के लिए ऑब्जेक्ट को कैसे पास करें

क्या मुझे पॉइंटर्स, संदर्भ, या गैर-सूचक और गैर-संदर्भ मानों को पारित करने की आवश्यकता है? मुझे याद है जावा में ऐसी कोई समस्या नहीं है क्योंकि हम केवल उस वेरिएबल को पास करते हैं जो वस्तुओं के संदर्भ में रखता है।

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

वेब के समाधान से एकत्रित समाधान "सी ++ में कार्य करने के लिए ऑब्जेक्ट कैसे पास करें?"

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

मूल्य से गुजारें, सिवाय इसके कि जब

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

पॉइंटर द्वारा पासिंग वास्तव में कभी सलाह नहीं दी गई है। वैकल्पिक पैरामीटर को boost::optional रूप में सबसे अच्छा व्यक्त किया जाता है, और संदर्भ के द्वारा अलियासिंग ठीक किया जाता है

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


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

const रेफरल द्वारा तर्कों को पास करें, सिवाय इसके कि जब

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

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


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

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

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

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

मूल्य से गुजारें (और पास-बाय-पॉइंटर)

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

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

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

समीकरण को जोड़ना

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

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

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

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

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

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

पक्षीय लेख

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

 // 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 } } 

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

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

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

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

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

… और वैकल्पिक

 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); 

ये घोषणा वास्तव में ठीक उसी फ़ंक्शन हैं! मूल्य से गुजरते समय, 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 

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

 void func (vector v) 

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

डाउनसाइड ऑब्जेक्ट की प्रतिलिपि करने के लिए खर्च किए गए CPU चक्र और अतिरिक्त मेमोरी है।

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

 void func (const vector & v); 

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

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

गैर-संविधान संदर्भ से पास करें:

 void func (vector & v) 

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

कॉन्स्ट संदर्भ मामले की तरह, यह धागा सुरक्षित नहीं है

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

 void func (const vector * vp); 

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

थ्रेड सुरक्षित नहीं।

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

 void func (vector * vp); 

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

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

बस संदर्भ / सूचक द्वारा सभी पास की तरह, थ्रेड सुरक्षित नहीं।

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

 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 } 

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

पैरामीटर के रूप में किसी वस्तु को किसी ऑब्जेक्ट को पास करने के तीन तरीके हैं:

  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; } 

आउटपुट:

कहो मैं कुछ फ़ंक्श में हूँ
सूचक का मान -17891602 है
चर का मान 4 है

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(); }