2011-02-08 13 views
11

तो, इसके लिए हर जगह खोजबीन के बाद, मैं एक वर्ग तीर ऑपरेटर बनाने का तरीका खोजने के लिए, नहीं कर पा रहे, यानी,मैं कक्षा तीर ऑपरेटर कैसे बना और उपयोग करूं?

class Someclass 
{ 
    operator->() /* ? */ 
    { 
    } 
}; 

मैं सिर्फ पता है कि कैसे इसके साथ काम करके उससे उचित उपयोग करने के लिए की जरूरत है। - इसके इनपुट क्या हैं? - यह क्या लौटता है? - मैं इसे सही तरीके से घोषित/प्रोटोटाइप कैसे करूं?

+3

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

उत्तर

14

ऑपरेटर के लिए अनुवाद किया जाएगा -> सदस्य पहुँच ओवरलोड प्रयोग किया जाता है । एक छोटा सा उदाहरण:

#include <iostream> 
struct A 
{ 
    void foo() {std::cout << "Hi" << std::endl;} 
}; 

struct B 
{ 
    A a; 
    A* operator->() { 
     return &a; 
    } 
}; 

int main() { 
    B b; 
    b->foo(); 
} 

यह आउटपुट:

Hi 
+0

क्या तीर ऑपरेटर संरचना सदस्यों को वापस करने के लिए भी काम करता है क्योंकि यह वर्ग के सदस्य करता है? – Codesmith

+0

यह संरचना सदस्यों को आसानी से वापस कर सकता है जैसे कि यह कक्षा के सदस्यों को वापस कर सकता है। जब आप तीर का उपयोग करते हैं तो ऑपरेटर के शरीर ->() सदस्य फ़ंक्शन द्वारा निर्धारित किया जाता है। रेखा "वापसी और एक;" जो कुछ भी आप तय करते हैं उसे वापस करने के लिए बदला जा सकता है। – Darryl

0

"तीर" ऑपरेटर द्वारा अतिभारित किया जा सकता:

a->b 

return_type my_class::operator->() 
+0

यह इतना आसान नहीं है, 'return_type {} ->() ->() ->() ... ->() को वैध कोड होने के लिए एक सूचक होना चाहिए। – alfC

16

तीर ऑपरेटर कोई आदानों है। तकनीकी रूप से, यह जो कुछ भी आप चाहते हैं उसे वापस कर सकते हैं, लेकिन इसे कुछ ऐसा वापस करना चाहिए जो या तो सूचक है या एक सूचक through chained -> operators बन सकता है।

-> ऑपरेटर स्वचालित रूप से निर्मित संकेतक भिन्नता, नहीं operator* का उपयोग कर अपने तर्क कॉल करने से पहले अपनी वापसी मान dereferences ताकि आप निम्नलिखित वर्ग हो सकता है:

class PointerToString 
{ 
    string a; 

    public: 
    class PtPtS 
    { 
     public: 
     PtPtS(PointerToString &s) : r(s) {} 
     string* operator->() 
     { 
      std::cout << "indirect arrow"; 
      return &*r; 
     } 
     private: 
     PointerToString &r; 
    }; 

    PointerToString(const string &s) : a(s) {} 
    PtPts operator->() const 
    { 
     std::cout << "arrow dereference\n"; 
     return *this; 
    } 
    string &operator*() const 
    { 
     std::cout << "dereference\n"; 
     return a; 
    } 
}; 

इसे पसंद का प्रयोग करें:

PointerToString ptr(string("hello")); 
string::size_type size = ptr->size(); 

जिसमें संकलक द्वारा परिवर्तित किया जाता है:

string::size_type size = (*ptr.operator->().operator->()).size(); 

(साथ के रूप में कई .operator->() के रूप में एक वास्तविक सूचक वापस जाने के लिए आवश्यक) और आउटपुट

arrow dereference 
indirect dereference 
dereference 

ध्यान दें, तथापि, आप निम्न कर सकते हैं कि होना चाहिए:

PointerToString::PtPtS ptr2 = ptr.operator->(); 

Stroupstrup से:

ऑब्जेक्ट का परिवर्तन पी सूचक में p.operator->() सदस्य एम पर निर्भर नहीं है। यही वह अर्थ है जिसमें operator->() एक यूनरी पोस्टफिक्स ऑपरेटर है। हालांकि, कोई नया वाक्यविन्यास पेश नहीं किया गया है, इसलिए ->

+0

इस कोड को एक सभ्य कंपाइलर पर संकलित करने का कोई तरीका नहीं है। –

+0

@ सेबेस्टियन रेडल, आप सही हैं। मैंने स्पष्टीकरण और उदाहरण अपडेट किया है ताकि यह संकलित हो। –

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