81

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

+9

आपका प्रश्न वास्तव में केवल बाइनरी ऑपरेटरों के बारे में है। सभी ओवरलोडेड ऑपरेटर एक पैरामीटर तक ही सीमित नहीं हैं।() ऑपरेटर किसी भी पैरामीटर ले सकता है। दूसरी ओर, यूनरी ऑपरेटरों के पास कोई पैरामीटर नहीं हो सकता है। –

+1

http://stackoverflow.com/a/4421729/103167 –

+2

यह [सी ++ एफएक्यू: ऑपरेटर अधिभार] में शामिल कई विषयों में से एक है (http://stackoverflow.com/questions/4421706/operator-overloading) –

उत्तर

101

यदि आप अपने ऑपरेटर ओवरलोडेड फ़ंक्शन को सदस्य फ़ंक्शन के रूप में परिभाषित करते हैं, तो कंपाइलर s1 + s2 जैसे s1.operator+(s2) में अभिव्यक्ति का अनुवाद करता है। इसका मतलब है, ऑपरेटर ओवरलोडेड सदस्य फ़ंक्शन को पहले ऑपरेंड पर बुलाया जाता है। इस प्रकार सदस्य कार्य कैसे काम करते हैं!

लेकिन क्या होगा यदि पहला ऑपरेंड कक्षा नहीं है? अगर हम एक ऑपरेटर को अधिभारित करना चाहते हैं तो एक बड़ी समस्या है जहां पहला ऑपरेंड कक्षा प्रकार नहीं है, बल्कि double कहें। तो आप इस 10.0 + s2 की तरह लिख नहीं सकते हैं। हालांकि, आप s1 + 10.0 जैसे अभिव्यक्तियों के लिए ऑपरेटर ओवरलोडेड सदस्य फ़ंक्शन लिख सकते हैं।

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

class Sample 
{ 
public: 
    Sample operator + (const Sample& op2); //works with s1 + s2 
    Sample operator + (double op2); //works with s1 + 10.0 

    //Make it `friend` only when it needs to access private members. 
    //Otherwise simply make it **non-friend non-member** function. 
    friend Sample operator + (double op1, const Sample& op2); //works with 10.0 + s2 
} 

इन पढ़ें:
A slight problem of ordering in operands
How Non-Member Functions Improve Encapsulation

+2

"इसे 'दोस्त बनाएं' जब इसे निजी सदस्यों तक पहुंचने की आवश्यकता हो ... और जब आप एक्सेसर्स लिखने के लिए ऊब गए हों, तो सही? – badmaash

+4

@Ahihi: अपना चयन चुनें: बेहतर Encapsulation बनाम आलसी लेखन आदत! – Nawaz

+0

क्या ज्ञात हैं ऐसे मामले जहां आप ग्लोबल 'ऑपरेटर +()' द्वारा 'दोस्त' कीवर्ड से बच नहीं सकते थे, बस 'वापसी op2.operator + (op1) हो; '? दोनों मामलों में, + डिफ़ॉल्ट रूप से इनपुट नमूना को संशोधित नहीं करेगा, और इसके बजाय 'नमूना' का एक नया रैल्यू उदाहरण लौटाएं, है ना? – matthias

14

यह नहीं है जरूरी friend ऑपरेटर भार के और सदस्य समारोह ऑपरेटर भार के यह वैश्विक ऑपरेटर भार के और सदस्य समारोह ऑपरेटर भार के बीच है के रूप में के बीच एक अंतर। एक वैश्विक ऑपरेटर अधिभार को पसंद करते हैं

एक कारण यह है अगर तुम जहां वर्ग प्रकार एक द्विआधारी ऑपरेटर की सही ओर दिखाई देता है भाव की अनुमति देना चाहते है। उदाहरण के लिए:

Foo f = 100; 
int x = 10; 
cout << x + f; 

यह केवल काम करता है अगर वहाँ

फू ऑपरेटर + (int x, स्थिरांक फू & च) के लिए एक वैश्विक ऑपरेटर अधिभार है;

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

परवाह किए बिना, यदि Foo केवल एक सदस्य समारोह ऑपरेटर अधिभार, की तरह था:

class Foo 
{ 
    ... 
    Foo operator + (int x); 
    ... 
}; 

... तो हम केवल जहां एक Foo उदाहरण पर दिखाई देता है भाव है करने में सक्षम होगा प्लस की छोड़ दिया ऑपरेटर।

+1

+ सदस्य और मित्र कार्यों के बजाय सदस्य कार्यों और गैर-सदस्य कार्यों के बीच भेद बनाने के लिए 1। मुझे लगता है कि आज हम "ग्लोबल या नेमस्पेस स्कोप" कहेंगे। –

संबंधित मुद्दे