आप 'क्यों नहीं ओवरलोड कर सकते हैं।' सी ++ में ऑपरेटर?


79

यह अतिभारित करने में सक्षम होने के लिए बहुत उपयोगी होगा। C ++ में ऑपरेटर और किसी ऑब्जेक्ट का संदर्भ लौटाता है।

आप को ओवरलोड कर सकते हैं operator->और operator*नहीं बल्किoperator.

क्या इसका कोई तकनीकी कारण है?


4
जब आप ओवरराइड करना चाहते हैं तो क्या आप इसका उदाहरण दे सकते हैं। ऑपरेटर?
तून Krijthe

4
आम तौर पर, उपयोग का मामला "स्मार्ट संदर्भ" है। एक प्रकार का प्रॉक्सी।
ddaa

2
@ गमेकट: इस प्रस्ताव के माध्यम से पढ़ें कि अधिभार की क्षमता को जोड़ने के लिए operator.और operator.*, इसके कुछ उदाहरण हैं।
मकर संक्राति

1
@ToonKrijthe रिक्त स्थान के .लिए अनुमति दी जाती है, इसलिए शायद कुछ होशियार लेकिन गतिशील प्रेषण हैक कि डॉट उत्पाद व्यक्त करने की अनुमति देता है matrix1 . matrix2
mwcz

जवाबों:


62

बज्ने स्ट्रॉस्ट्रुप के इस उद्धरण को देखें :

ऑपरेटर । (डॉट) सिद्धांत रूप में उसी तकनीक का उपयोग करके अतिभारित किया जा सकता है जैसे -> के लिए उपयोग किया जाता है। हालांकि, ऐसा करने से सवाल उठ सकते हैं कि क्या ऑब्जेक्ट ओवरलोडिंग के लिए एक ऑपरेशन है। या द्वारा संदर्भित एक वस्तु। उदाहरण के लिए:

class Y {
public:
    void f();
    // ...
};

class X {    // assume that you can overload .
    Y* p;
    Y& operator.() { return *p; }
    void f();
    // ...
};

void g(X& x)
{
    x.f();    // X::f or Y::f or error?
}

इस समस्या को कई तरीकों से हल किया जा सकता है। मानकीकरण के समय, यह स्पष्ट नहीं था कि कौन सा तरीका सबसे अच्छा होगा। अधिक जानकारी के लिए, C ++ का डिज़ाइन और विकास देखें ।


मेरे जवाब में TDaEoC ++ से पूर्ण उद्धरण।
ddaa

15
मुझे यह साहित्यिक चोरी / पुनरावृत्ति के लिए वोट करने के लिए लुभाया जाता है। जब उद्धृत करते हैं, तो शब्दशः उद्धृत करें, ट्वीक न करें। और बोली स्वरूपों का उपयोग करें।
सेबेस्टियन मच

2
इसका उदाहरण सिर्फ ओवरलोड रिज़ॉल्यूशन अस्पष्टता है, जो अधिक सावधानीपूर्वक प्रोग्रामिंग की आवश्यकता की ओर इशारा करता है (देखें: stackoverflow.com/questions/13554606/… ) यह स्थिति ओवरलोड नहीं करने के कारण के रूप में नहीं होनी चाहिएoperator .
स्लैशमाई

@ शशमिस सं। का औचित्य operator.एक स्पष्ट समानांतर है operator->। और आप ओवरलोडिंग रिज़ॉल्यूशन कैसे कर सकते हैं?
जिज्ञासु

बस ध्यान दें कि बाद में, बज़्ने स्ट्रॉस्ट्रप ऑपरेटर डॉट के पक्ष में था और यहां तक ​​कि उसके लिए एक प्रस्ताव भी रखा था, जो कि जाहिरा तौर पर (अभी तक) स्वीकार नहीं किया गया था: http://www.open-std.org/jtc1/sc22/wg21/ डॉक्स / पेपर्स / 2015 / n4477.pdf - @emlai द्वारा पहले से ही इस प्रश्न के लिए एक टिप्पणी के रूप में जोड़ा गया
आमिर किर्ष

52

स्ट्रॉस्ट्रुप ने कहा कि C ++ एक एक्सटेंसिबल होना चाहिए, लेकिन म्यूट भाषा नहीं।

ओवरलोडिंग की अनुमति देने के लिए डॉट (विशेषता पहुंच) ऑपरेटर को भाषा के मूल के बहुत करीब देखा गया था।

सी ++ का डिजाइन और विकास देखें , पृष्ठ 242, अनुभाग 11.5.2 स्मार्ट संदर्भ

जब मैंने ऑपरेटर को ओवरलोडिंग की अनुमति देने का फैसला किया ->, तो मैंने स्वाभाविक रूप से विचार किया कि क्या ऑपरेटर .इसी तरह से ओवरलोड हो सकता है।

उस समय, मैंने निम्नलिखित तर्कों को निर्णायक माना: यदि objएक वर्ग वस्तु है तो उस वस्तु के वर्ग के obj.mप्रत्येक सदस्य mके लिए एक अर्थ है । हम अंतर्निहित कार्यों को पुनर्परिभाषित करके भाषा को परिवर्तनशील नहीं बनाने का प्रयास करते हैं (हालांकि उस नियम =का सख्त आवश्यकता से बाहर उल्लंघन किया जाता है, और एकता के लिए &)।

यदि हमने .किसी वर्ग के लिए ओवरलोडिंग की अनुमति दी है X, तो हम Xसामान्य तरीकों से सदस्यों तक पहुंचने में असमर्थ होंगे ; हम एक सूचक है और उपयोग करने के लिए होता ->है, लेकिन ->और &भी फिर से परिभाषित किया गया हो सकता है। मुझे एक एक्स्टेंसिबल लैंग्वेज चाहिए थी, एक म्यूट नहीं।

ये तर्क वजनदार हैं, लेकिन निर्णायक नहीं हैं। विशेष रूप से, 1990 में जिम एडकॉक ऑपरेटर की ओवरलोडिंग अनुमति देने के लिए प्रस्तावित . वास्तव में जिस तरह से ऑपरेटर ->है।

इस उद्धरण में "मैं" ब्रेज़ेन स्ट्रॉस्ट्रुप है। आप इससे अधिक आधिकारिक नहीं हो सकते।

यदि आप वास्तव में C ++ को समझना चाहते हैं (जैसे कि "यह ऐसा क्यों है"), तो आपको इस पुस्तक को बिल्कुल पढ़ना चाहिए।


28

स्ट्रॉस्ट्रुप के पास इस प्रश्न का उत्तर है :

ऑपरेटर । (डॉट) सिद्धांत रूप में उसी तकनीक का उपयोग करके अतिभारित किया जा सकता है जैसे -> के लिए उपयोग किया जाता है। हालांकि, ऐसा करने से सवाल उठ सकते हैं कि क्या ऑब्जेक्ट ओवरलोडिंग के लिए एक ऑपरेशन है। या द्वारा संदर्भित एक वस्तु। उदाहरण के लिए:

class Y {
public:
    void f();
    // ...
};
class X {   // assume that you can overload .
    Y* p;
    Y& operator.() { return *p; }
    void f();
    // ...
};
void g(X& x)
{
    x.f();  // X::f or Y::f or error?
}

इस समस्या को कई तरीकों से हल किया जा सकता है। मानकीकरण के समय, यह स्पष्ट नहीं था कि कौन सा तरीका सबसे अच्छा होगा। अधिक जानकारी के लिए, डी एंड ई देखें ।


1
एंटोन के जवाब पर मेरी टिप्पणी देखें
स्लैशमाईज़

1

यह समझना बहुत आसान है, यदि आप ऑपरेटर फ़ंक्शन इनवोकेशन के आंतरिक तंत्र के माध्यम से जाते हैं, तो कहें कि एक क्लास कॉम्प्लेक्स में वास्तविक भाग के लिए दो सदस्य हो सकते हैं और मैं काल्पनिक भाग के लिए। कहो कॉम्प्लेक्स C1 (10,20), C2 (10,2) // हम मानते हैं कि कक्षा के भीतर पहले से ही दो तर्क रचनाकार हैं। अब यदि आप एक कथन के रूप में C1 + C2 लिखते हैं तो कंपाइलर जटिल संख्या पर + ऑपरेटर के ओवरलोड संस्करण को खोजने का प्रयास करता है। अब हम मानते हैं कि मैं अधिभार + संचालक है, इसलिए C1 + C2 आंतरिक रूप से c1.operator + (c2) के रूप में अनुवादित किया गया है। अब मान लीजिए कि जब आप ओवरलोड कर सकते हैं तो '।' ऑपरेटर। तो अब लगता है कि निम्नलिखित कॉल C1.disp () // एक जटिल वस्तु की प्रदर्शन सामग्री है। अब आंतरिक प्रतिनिधित्व के रूप में प्रतिनिधित्व करने का प्रयास करें C1.operator; (------) , पूरी तरह से गड़बड़ चीजें। यही कारण है कि हम अधिक भार नहीं उठा सकते। ' ऑपरेटर


1
कुछ लोग कहते हैं कि आंतरिक अनुवादित को अतिभारित नहीं होना चाहिएoperator.
जिज्ञासु

यह कैसे उपयोगी हो सकता है और इतना गन्दा कैसे हो सकता है, इसके लिए एक C ++ का प्रस्ताव देखें: http://www.open-std.org/jtc1/sc22/wg21/docs/p/2015/n4477.pdf
अमीर किरन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.