2009-02-06 18 views
67

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

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

वहाँ इस के लिए एक तकनीकी कारण है?

+4

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

+4

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

+2

@Gamecat: [this] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1671.pdf) के माध्यम से पढ़ें 'ऑपरेटर' को अधिभारित करने की क्षमता जोड़ने का प्रस्ताव। 'ऑपरेटर। *', इसमें कुछ उदाहरण हैं। – Mankarse

उत्तर

51

this quote from Bjarne Stroustrup देखें:

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

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

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

+0

मेरे उत्तर में TDaEoC++ से पूर्ण उद्धरण। – ddaa

+12

मुझे साहित्य चोरी/पुनर्विचार के लिए इसे वोट देने का लुत्फ उठाना है। उद्धरण देते समय, शब्दशः उद्धरण, tweak मत करो। और उद्धरण प्रारूपों का उपयोग करें। –

+0

बहुत अच्छा उदाहरण और स्पष्टीकरण। – Manju

27

Stroustrup has an answer for this question:

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

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

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

+0

एंटोन के उत्तर पर मेरी टिप्पणी देखें – slashmais

47

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

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

The Design and Evolution of C++, पृष्ठ 242, सेक्शन 11.5.2 स्मार्ट संदर्भ देखें।

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

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

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

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

इस उद्धरण में "मैं" Bjarne Stroustrup है। आप उससे अधिक आधिकारिक नहीं हो सकते हैं।

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

1

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

+1

कुछ लोग कहते हैं कि आंतरिक अनुवाद को अधिभारित 'ऑपरेटर' नहीं कहा जाना चाहिए। – curiousguy

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