दिलचस्प पोस्ट
आप एक MySQL क्वेरी में स्ट्रिंग से एक संख्यात्मक मान कैसे निकाल सकते हैं? आप पायथन में SQLite तालिका / स्तंभ नामों के लिए स्ट्रिंग कैसे बचते हैं? PHP और fgetcsv फ़ंक्शन का उपयोग करते हुए सीएसवी फ़ाइल से एक सरणी कैसे बनाएं मुझे 'सच' की उम्मीद है लेकिन 'कोई नहीं' Xcode त्रुटि "डेवलपर डिस्क छवि नहीं मिल सका" ओडीबीसी के बिना जावा से ऐक्सेस डाटाबेस को जोड़ना नुम्पी: मूल्य का पहला सूचकांक तेजी से ढूंढें फ़ाइल सिस्टम निर्देशिका संरचना के साथ TreeView को पॉप्युलेट करें सी +11: एकाधिक सदियों में वर्ग-सदस्य को अलग-थलग करना अजगर अनुरोध फ़ाइल अपलोड करें घातक त्रुटि: अपरिभाषित विधि को कॉल mysqli_stmt :: fetch_array () सर्वर से डेटा प्राप्त करने का अनुशंसित तरीका जावा की पेंट विधि के साथ समस्याएं, हास्यास्पद रीफ्रेश वेग .MSI और setup.exe फ़ाइल के बीच विशिष्ट अंतर क्या हैं? VARCHAR से INT – MySQL को कास्ट करें

असाइनमेंट ऑपरेटर को ओवरलोड करने के लिए गैर सदस्यीय फ़ंक्शन का उपयोग क्यों नहीं किया जा सकता?

एक सदस्य फ़ंक्शन का उपयोग करके असाइनमेंट ऑपरेटर ओवरलोड किया जा सकता है, लेकिन गैर-सदस्यीय friend कार्य नहीं:

 class Test { int a; public: Test(int x) :a(x) {} friend Test& operator=(Test &obj1, Test &obj2); }; Test& operator=(Test &obj1, Test &obj2)//Not implemented fully. just for test. { return obj1; } 

यह इस त्रुटि का कारण बनता है:

त्रुटि C2801: 'ऑपरेटर =' एक गैर-स्थिर सदस्य होना चाहिए

असाइनमेंट ऑपरेटर को ओवरलोड करने के लिए friend समारोह का उपयोग क्यों नहीं किया जा सकता? कंपाइलर अन्य ऑपरेटरों को ओवरलोड करने की अनुमति दे रहा है जैसे कि += और -= friend का उपयोग करना operator= में अंतर्निहित समस्या / सीमा क्या है?

वेब के समाधान से एकत्रित समाधान "असाइनमेंट ऑपरेटर को ओवरलोड करने के लिए गैर सदस्यीय फ़ंक्शन का उपयोग क्यों नहीं किया जा सकता?"

क्योंकि डिफॉल्ट operator= कंपाइलर द्वारा प्रदान किया गया (एक सदस्यीय प्रतिलिपि कॉपी) हमेशा प्राथमिकता लेता है Ie आपके मित्र operator= कभी भी नहीं बुलाया जाएगा।

संपादित करें: यह जवाब इस का जवाब दे रहा है

क्या ऑपरेटर में निहित समस्या / सीमा है?

प्रश्न का भाग अन्य जवाब यहां दिए गए मानक के हिस्से का हवाला देते हैं जो कहते हैं कि आप ऐसा नहीं कर सकते, लेकिन यह सबसे अधिक संभावना है कि मानक के उस हिस्से को उस तरीके से क्यों लिखा गया था।

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

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

अगर भाषा को कॉपी-असाइनमेंट ऑपरेटर को स्टैंडअलोन (गैर-सदस्य) फ़ंक्शन के रूप में घोषित करने की अनुमति भी दी गई है, तो आप निम्न के साथ समाप्त कर सकते हैं

 // Class definition class SomeClass { // No copy-assignment operator declared here // so the compiler declares its own implicitly ... }; SomeClass a, b; void foo() { a = b; // The code here will use the compiler-declared copy-assignment for `SomeClass` // because it doesn't know anything about any other copy-assignment operators } // Your standalone assignment operator SomeClass& operator =(SomeClass& lhs, const SomeClass& rhs); void bar() { a = b; // The code here will use your standalone copy-assigment for `SomeClass` // and not the compiler-declared one } 

जैसा कि उपरोक्त उदाहरण में देखा गया है, प्रतिलिपि असाइनमेंट का अर्थांतरण इकाई के मध्य में बदल जाएगा – आपके स्टैंडअलोन ऑपरेटर की घोषणा से पहले कंपाइलर का संस्करण उपयोग किया जाता है। घोषणापत्र के बाद आपके संस्करण का उपयोग किया जाता है। आप अपने स्टैंडअलोन प्रति-असाइनमेंट ऑपरेटर की घोषणा कहां के आधार पर प्रोग्राम का व्यवहार बदल जाएगा।

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

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

$ 13.5.3 – "एक असाइनमेंट ऑपरेटर एक गैर-स्टैटिक सदस्य फ़ंक्शन द्वारा बिल्कुल एक पैरामीटर के साथ लागू किया जाएगा। क्योंकि प्रतिलिपि असाइनमेंट ऑपरेटर = एक वर्ग के लिए निहित घोषित किया जाता है, अगर उपयोगकर्ता द्वारा घोषित नहीं किया गया है (12.8), एक बेस क्लास असाइनमेंट ऑपरेटर को हमेशा व्युत्पन्न वर्ग की कॉपी असाइनमेंट ऑपरेटर द्वारा छुपाया जाता है। "

क्योंकि कुछ ऑपरेटरों को सदस्य होना चाहिए। ये ऑपरेटर हैं:
operator[]
operator=
operator()
operator->

और operator int जैसे operator int ऑपरेटर टाइप करें।

यद्यपि कोई यह बता सकता है कि वास्तव में ऑपरेटर = सदस्य क्यों होना चाहिए, उनका तर्क सूची में दूसरों पर लागू नहीं हो सकता है, जिससे मुझे विश्वास हो जाता है कि "क्यों" का जवाब "सिर्फ इसलिए" है।

HTH

operator= एक विशेष सदस्य फ़ंक्शन है, जो कि कंपाइलर प्रदान करेगा यदि आप इसे स्वयं घोषित नहीं करते हैं operator= की इस विशेष स्थिति की वजह से operator= यह समझ में आता है कि आरएसएस के लिए यह एक सदस्य फ़ंक्शन बनने की आवश्यकता है, इसलिए इसमें कोई संकलक-उत्पन्न सदस्य operator= और उपयोगकर्ता घोषित मित्र operator= और दोनों के बीच चयन करने की कोई संभावना नहीं है दो।

असाइनमेंट ऑपरेटर ओवरलोड करने के लिए मित्र फ़ंक्शन का उपयोग क्यों नहीं किया जा सकता?

संक्षिप्त जवाब: सिर्फ इसलिए कि

कुछ हद तक अब उत्तर: यह तरीका है कि वाक्यविन्यास तय किया गया था। कुछ ऑपरेटरों को सदस्य कार्य करना होगा असाइनमेंट ऑपरेटर में से एक है,

operator= का इरादा operator= वर्तमान ऑब्जेक्ट के लिए असाइनमेंट ऑपरेशन है। तब एलएचएस, या लावल्यू, एक ही प्रकार का एक वस्तु है।

उस मामले पर विचार करें जहां एलएचएस एक पूर्णांक या कुछ अन्य प्रकार है। यह operator int() या एक इसी operator T() फ़ंक्शन द्वारा संभाला जाने वाला मामला है। इसलिए एलएचएस का प्रकार पहले से परिभाषित है, लेकिन एक गैर-सदस्यीय operator= फ़ंक्शन इस का उल्लंघन कर सकता है।

इसलिए इसे टाला जाता है।

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

यह पोस्ट सी ++ 11 पर लागू होता है

किसी को एक गैर-सदस्यीय operator= क्यों चाहिए? ठीक है, एक सदस्य operator= तो निम्न कोड संभव है:

 Test const &ref = ( Test() = something ); 

जो एक लटकती संदर्भ बनाता है एक गैर-सदस्यीय ऑपरेटर यह तय करेगा:

 Test& operator=(Test &obj1, Test obj2) 

क्योंकि अब प्राइवेट Test() obj1 को बाध्य करने में विफल होगा। वास्तव में यह हस्ताक्षर यह लागू करेगा कि हम कभी भी एक झुकाव के संदर्भ (जब तक कि हम निश्चित रूप से एक के साथ आपूर्ति नहीं करते) वापस नहीं करते – फ़ंक्शन हमेशा "मान्य" लौवेल देता है क्योंकि यह एक लावल्यू के साथ बुलाया जा रहा है।

हालांकि सी ++ 11 में अब यह निर्दिष्ट करने का एक तरीका है कि सदस्य फ़ंक्शन को केवल लावलुओं पर बुलाया जा सकता है, ताकि आप सदस्य फ़ंक्शन लिखकर एक ही लक्ष्य प्राप्त कर सकें।

 Test &operator=(Test obj2) & // ^^^ 

अब लटकती संदर्भ वाला उपरोक्त कोड संकलन करने में विफल होगा।


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