2011-02-07 21 views
6

संभव डुप्लिकेट:
Overloading operator ->ऑपरेटर-> पॉइंटर्स के लिए "जंजीर" है?

हाय,

मैंने देखा है कि operator->() श्रृंखलित है (फिर से लागू) के बाद यह मूल्यांकन किया जाता है, उदाहरण के लिए:

struct Bar 
{ 
    Bar() : m_str("Hello world!") {} 
    const string* operator->() const { return &m_str; } 
    string m_str; 
}; 

struct Foo 
{ 
    const Bar& operator->() const { return m_bar; } 
    Bar m_bar; 
}; 

int main() 
{ 
    Foo f; 
    cout << f->c_str() << endl; 
    return 0; 
} 

बहुत बढ़िया काम करता है, जिसके लिए आवश्यक है मूल्यांकन के लिए तीन operator->() - Foo::operator->(), Bar::operator->() और नियमित सूचक संकल्प।

लेकिन यह मध्य में पॉइंटर्स के साथ काम नहीं करेगा - अगर Foo::operator->() संदर्भ के बजाय बार में पॉइंटर लौटाता है, तो यह संकलित नहीं होगा। उदाहरण के लिए auto_ptr<auto_ptr<string>> के साथ ही होता है।

क्या यह गैर-अधिभारित operator->() के लिए विशिष्ट है, इसलिए यह केवल एक बार लागू होता है और चेनिंग का कारण नहीं बनता है? (*ptr2)-> ... का उपयोग किए बिना नीचे दिए गए कोड को बनाना संभव है?

int main() 
{ 
    string s = "Hello world"; 
    auto_ptr<string> ptr1(&s); 
    auto_ptr<auto_ptr<string> > ptr2(&ptr1); 
    cout << ptr1->c_str() << endl; // fine 
    cout << ptr2->c_str() << endl; // breaks compilation 
} 

धन्यवाद!

+0

[ओवरलोडिंग ऑपरेटर ->] (http://stackoverflow.com/questions/4896238/overloading-operator) का डुप्लिकेट [एंड्रीटी का जवाब 'ऑपरेटर->' के व्यवहार और "चेनिंग" कैसे होता है।] –

+1

@ जेम्स मैं इस खुले रखने के पक्ष में सवाल उठाने के पक्ष में अलग हूं। यह अन्य लोगों को उस उत्तर को खोजने में मदद कर सकता है। –

+2

@ जुज: एक बंद प्रश्न स्वचालित रूप से हटाया नहीं जाता है, और इस तरह एक अच्छी तरह से पूछे जाने वाले प्रश्न को हटाया नहीं जाएगा; सवाल अभी भी मौजूद होगा और खोजने योग्य होगा। –

उत्तर

12

सी ++ 98 मानक §13.5.6/1 "वर्ग सदस्य पहुँच":

कोई व्यंजक x->m प्रकार T अगर T::operator-> मौजूद है के एक वर्ग वस्तु x के लिए और अगर ऑपरेटर है (x.operator->())->m के रूप में व्याख्या की है ओवरलोड रिज़ॉल्यूशन तंत्र (13.3) द्वारा सर्वोत्तम मिलान फ़ंक्शन में चुना गया।

क्या इस अभ्यास में अर्थ है कि जब x एक सूचक है, आप ’ डॉन टी चेनिंग मिलता है; फिर आप operator-> (यानी x->mx के साथ (*x).m पर अनुवादित) प्राप्त करें।

लेकिन जब x वर्ग प्रकार T का एक ऑब्जेक्ट है, तो आप चेनिंग प्रभाव प्राप्त कर सकते हैं।क्योंकि (x.operator->())->m के रूप में व्याख्या (x.operator->()) कक्षा U कहकर स्वयं कुछ वर्ग का एक वस्तु हो सकती है। दूसरे -> को U::operator-> के रूप में हल किया जा सकता है, और इसी तरह, यदि इसका परिणाम फिर से एक वर्ग प्रकार वस्तु और नरक है;

अपने मामले में, Foo::operator-> कक्षा Bar की एक वस्तु (संदर्भ) का एक उत्पाद (संदर्भ) उत्पन्न करता है, जो operator-> को परिभाषित करता है।

लेकिन जब operator-> एक सूचक देता है, उदाहरण के लिए std::auto_ptr<T>::operator-> करता है, तो यह केवल अंतर्निहित operator-> है जिसका उपयोग किया जाता है।

गुजरने में, delete का उपयोग करने से व्यावहारिक रूप से किसी को रोकने के लिए उपयोग किया जा सकता है। std::auto_ptr ऐसा नहीं करता है। और मैं ’ मैंने इसे कभी नहीं देखा है।

लेकिन एक बार एक स्मार्ट पॉइंटर द्वारा प्रबंधित कच्चे सूचक के अनजान delete को रोकने के तरीके के बारे में [comp.lang.C++। नियंत्रित] में एक बार एक लंबी चर्चा धागा था, और यह एक संभावना थी जिस पर चर्चा की गई थी।

चीयर्स & एचएचटी।

0

नहीं, यह काम करने के लिए संभव नहीं है। यदि आप string * के लिए operator -> ओवरलोड कर सकते हैं तो आप इसे काम कर सकते हैं। लेकिन operator -> में पहले से ही सभी पॉइंटर प्रकारों की परिभाषा है। तो, जैसे कि आप आदिम संख्यात्मक प्रकारों के लिए + अधिभारित नहीं कर सकते हैं, आप किसी भी सूचक प्रकार के लिए operator -> अधिभारित नहीं कर सकते हैं।

और यहां तक ​​कि यदि आप कर सकते हैं, तो संकलक को कैसे पता चल सकता है कि रिकर्सन समाप्त होना चाहिए?

3

आपका पहला उदाहरण काम करने का कारण यह है कि आपने एक सूचक के बजाय संदर्भ वापस कर दिया है। वह ऑपरेटर सामान्य रूप से अमान्य होगा अगर इसे ओवरलोड किया गया हो। इसलिए, कंपाइलर को श्रृंखला के नीचे अधिभारित कार्यों को निष्पादित करना होगा। हालांकि, auto_ptr के मामले में आपको वास्तव में एक वास्तविक सूचक वापस कर दिया जाता है और डिफ़ॉल्ट पॉइंटर्स के लिए डिफ़ॉल्ट operator -> लागू किया जाता है।

अधिक जानकारी के लिए कृपया Overloading operator -> प्रश्न देखें।

+0

उत्तर के लिए धन्यवाद। मैं वेक्टर > और इसी तरह की सामग्री को पुन: सक्रिय करने के लिए कोड को सरल बनाने के दृष्टिकोण की तलाश में था। ऐसा लगता है कि साझा_ptr (कुछ अन्य स्मार्ट ptrs) के लिए वेक्टर (किसी भी कंटेनर) इटरेटर को विशेषज्ञ बनाना एकमात्र विकल्प है, जो स्वीकार्य नहीं है। – nyrl