ओवरलोडिंग मेंबर एक्सेस ऑपरेटर ->, *


129

मैं सबसे ऑपरेटर ओवरलोडिंग को समझते हैं, सदस्य पहुँच ऑपरेटरों के अपवाद के साथ ->, .*, ->*आदि

विशेष रूप से, इन ऑपरेटर कार्यों को क्या पारित किया जाता है, और क्या लौटाया जाना चाहिए?

ऑपरेटर कैसे कार्य करता है (जैसे operator->(...)) जानता है कि किस सदस्य को संदर्भित किया जा रहा है? क्या यह पता चल सकता है? क्या यह जानना भी जरूरी है?

अंत में, क्या कोई आधार विचार है जिसे ध्यान में रखा जाना चाहिए? उदाहरण के लिए, किसी चीज को ओवरलोड करते समय operator[], आम तौर पर आपको एक कास्ट और नॉन-कास्ट संस्करण दोनों की आवश्यकता होगी। क्या सदस्य अभिगम संचालकों को कास्ट और नॉन-कास्ट संस्करण की आवश्यकता होती है?


1
मेरा मानना ​​है कि उपरोक्त C ++ - Faq उपरोक्त सभी Q के पूछे जाने पर छूता है।
आलोक सेव

constऔर गैर- constसंस्करणों की आवश्यकताoperator-> नहीं है , लेकिन दोनों प्रदान करना उपयोगी हो सकता है।
फ्रेड फू

1
इन्हें भी देखें: yosefk.com/c++fqa/operator.html
György Andrasek

9
@Als: THE पूछे जाने वाले प्रश्न की व्याख्या नहीं करता कैसे अधिभार के लिए ->*और .*। वास्तव में, यह भी उन्हें उल्लेख नहीं करता है! मुझे लगता है कि वे अक्सर पूछे जाने वाले प्रश्न के लिए दुर्लभ होते हैं, लेकिन मैं इस प्रश्न को अक्सर पूछे जाने वाले प्रश्न से जोड़ता हूं। कृपया इसे अकसर किये गए सवाल के जवाब के रूप में बंद न करें!
sbi

@sbi, मैं आपके (भयानक) FAQ से इस प्रश्न का लिंक खोजने में पूरी तरह से विफल रहा, और एक डुप्लिकेट प्रश्न पूछकर समाप्त हुआ। क्या आप इसे और अधिक स्पष्ट कर सकते हैं? (माफी अगर यह पहले से ही स्पष्ट है)।
पी आई

जवाबों:


144

->

यह केवल वास्तव में मुश्किल है। यह एक गैर-सदस्यीय कार्य होना चाहिए, और यह कोई तर्क नहीं लेता है। रिटर्न मान का उपयोग सदस्य लुकअप करने के लिए किया जाता है।

यदि रिटर्न वैल्यू, क्लास के प्रकार का एक और ऑब्जेक्ट है, न कि पॉइंटर, तो उसके बाद के मेंबर लुकअप को भी एक operator->फंक्शन द्वारा हैंडल किया जाता है। इसे "ड्रिल-डाउन व्यवहार" कहा जाता है। भाषा एक साथ operator->कॉल करती है जब तक कि आखिरी एक पॉइंटर नहीं देता।

struct client
    { int a; };

struct proxy {
    client *target;
    client *operator->() const
        { return target; }
};

struct proxy2 {
    proxy *target;
    proxy &operator->() const
        { return * target; }
};

void f() {
    client x = { 3 };
    proxy y = { & x };
    proxy2 z = { & y };

    std::cout << x.a << y->a << z->a; // print "333"
}

->*

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

दूसरे शब्दों में, यह एक बस की तरह एक सामान्य द्विआधारी ऑपरेटर है +, -और /। यह भी देखें: क्या फ्री ऑपरेटर -> * ओवरलोड बुराई?

.* तथा .

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

ओवरलोडिंग ->, ->*, ., और .*केवल ऐसे मामलों में भर सकते हैं जहां एक अभिव्यक्ति अपरिभाषित किया जाएगा, यह कभी नहीं एक अभिव्यक्ति है कि कोई अधिक भार के साथ मान्य होगा के अर्थ बदल सकते हैं।


2
आपका अंतिम कथन पूरी तरह से सत्य नहीं है। उदाहरण के लिए, आप newऑपरेटर को ओवरलोड कर सकते हैं , भले ही यह ओवरलोड होने पर भी मान्य हो।
मैट

6
@ अच्छी तरह से, newहमेशा अतिभारित होता है, या ओवरलोडिंग के नियम वास्तव में इस पर लागू नहीं होते हैं (13.5 / 5: आवंटन और निपटान कार्य, ऑपरेटर नया, ऑपरेटर नया [], ऑपरेटर हटाएं और ऑपरेटर हटाएं]], पूरी तरह से 3.7 में वर्णित हैं .4। गुण और प्रतिबंध इस उपखंड के बाकी हिस्सों में पाया उन्हें लागू नहीं जब तक स्पष्ट 3.7.4 में कहा गया है।) लेकिन एकल अधिक भार &या द्विआधारी &&, ||या ,, या के भार के जोड़ने operator=, या एक unscoped के लिए कुछ के बारे में अभी अधिक भार गणना प्रकार, एक अभिव्यक्ति का अर्थ बदल सकता है। कथन को स्पष्ट किया, धन्यवाद!
पोटाटोस्वाटर

41

संचालक -> विशेष है।

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

सुविधा के लिए अतिरिक्त कार्यक्षमता प्रदान की जाती है, इसलिए आपको कॉल करने की आवश्यकता नहीं है

a->->func();

आप बस कर सकते हैं:

a->func();

वह ऑपरेटर बनाता है -> अन्य ऑपरेटर ओवरलोड से अलग।


3
यह उत्तर अधिक श्रेय का हकदार है, आप उस लिंक से एक्सेल की पुस्तक डाउनलोड कर सकते हैं और जानकारी वॉल्यूम वन के अध्याय 12 में है।
पी आई

26

आप सदस्य पहुंच को अधिभार नहीं दे सकते .(यानी जो ->करता है उसका दूसरा भाग )। हालाँकि आप यूनीरी डेरीफेरिंग ऑपरेटर *(यानी जो ->करता है उसका पहला भाग ) को अधिभारित कर सकते हैं ।

C ++ ->ऑपरेटर मूल रूप से दो चरणों का संघ है और यह स्पष्ट है कि क्या आपको लगता है कि x->yइसके बराबर है (*x).y। सी ++ तुम क्या से कोई लेना देना अनुकूलित करने के लिए अनुमति देता है (*x)हिस्सा जब xअपनी कक्षा का एक उदाहरण है।

->ओवरलोडिंग के लिए अर्थ कुछ हद तक अजीब है क्योंकि C ++ आपको या तो एक नियमित पॉइंटर वापस करने की अनुमति देता है (जिसका उपयोग इंगित ऑब्जेक्ट को खोजने के लिए किया जाएगा) या किसी अन्य वर्ग का उदाहरण वापस करने के लिए यदि यह वर्ग भी एक ->ऑपरेटर प्रदान करता है । जब इस दूसरे मामले में इस नए उदाहरण से dereferenced ऑब्जेक्ट के लिए खोज जारी है।


2
महान व्याख्या! मुझे लगता है कि इसका मतलब के लिए समान है ->*, क्योंकि यह के रूप के बराबर है (*x).*?
बिंगो

10

->ऑपरेटर पता नहीं है क्या सदस्य की ओर इशारा किया जा रहा है, यह सिर्फ पर वास्तविक सदस्य पहुँच प्रदर्शन करने के लिए एक वस्तु प्रदान करता है।

इसके अतिरिक्त, मुझे कोई कारण नहीं दिखाई देता है कि आप कांस्ट और नॉन-कास्ट संस्करण क्यों नहीं प्रदान कर सकते हैं।


7

जब आप ऑपरेटर को ओवरलोड करते हैं -> () (कोई तर्क यहां पारित नहीं किया जाता है), तो कंपाइलर वास्तव में क्या कर रहा है -> पुनरावर्ती जब तक यह एक प्रकार से वास्तविक पॉइंटर नहीं लौटाता है। यह तब सही सदस्य / विधि का उपयोग करता है।

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

निरंतरता के लिए - यह टिप्पणियों और अन्य उत्तरों में उत्तर दिया गया है (आप कर सकते हैं, और चाहिए, दोनों प्रदान करें)।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.