2010-05-30 6 views
15

क्या यह समझ में नहीं आता है कि p->m(*p).m के लिए सिंटैक्टिक चीनी थी? अनिवार्य रूप से, हर operator-> है कि मैंने कभी लिखा है इस प्रकार के रूप में लागू किया जा सकता था:ऑपरेटर-> मैन्युअल रूप से ओवरलोड क्यों किया जा सकता है?

Foo::Foo* operator->() 
{ 
    return &**this; 
} 

वहाँ किसी भी मामले में जहां मैं p->m(*p).m से कुछ और ही मतलब चाहेगा है? ऑपरेटर ओवरलोड> ... की जरूरत कभी नहीं

+1

यह इस तथ्य से स्वाभाविक रूप से पालन करता है कि 'x-> y' को' (x.operator ->()) -> y' के रूप में व्याख्या किया गया है कि यह रिकर्सन है। शायद उन्होंने सोचा कि यह रिकर्सन की अनुमति देने के लिए नुकसान नहीं पहुंचाएगा और इस प्रकार इसे मना नहीं किया? कम से कम मुझे एआरएम में कुछ स्पष्टीकरण नहीं मिला। –

उत्तर

18

operator->()की विचित्र भेद परोक्ष लागू किया जा रहा बार-बार जबकि वापसी प्रकार यह अनुमति देता है।

struct X { 
    int foo; 
}; 

struct Y { 
    X x; 
    X* operator->() { return &x; } 
}; 

struct Z { 
    Y y; 
    Y& operator->() { return y; } 
}; 

Z z; 
z->foo = 42;   // Works! Calls both! 

मैं, एक अवसर को याद है जब इस व्यवहार एक स्मार्ट सूचक की तरह संदर्भ में किसी अन्य वस्तु के लिए एक प्रॉक्सी के रूप में व्यवहार करने के लिए एक वस्तु सक्षम करना ज़रूरी था कि मैं कर सकते हैं: इस दिखाने के लिए स्पष्ट रास्ता कोड के साथ है विवरण याद नहीं है। मुझे याद है कि मैं इस काम को केवल अजीब विशेष मामले का उपयोग करके a->b सिंटैक्स का उपयोग करने के इरादे से व्यवहार करने के लिए व्यवहार कर सकता हूं; मुझे समान रूप से काम करने के लिए (*a).b प्राप्त करने का कोई तरीका नहीं मिला।

यह सुनिश्चित नहीं है कि यह आपके प्रश्न का उत्तर दे; वास्तव में मैं कह रहा हूं, "अच्छा सवाल है, लेकिन यह उससे भी कमजोर है!"

+1

+1 लेकिन भाषा अभी भी इस अजीब नियम को लागू कर सकती है भले ही 'ऑपरेटर->' भाषा में कड़ी मेहनत की गई हो, है ना? तकनीकी रूप से यह वाक्य रचनात्मक चीनी से थोड़ा अधिक होगा - * वाक्य रचनात्मक सिरप * शायद? – fredoverflow

+2

क्या आपका मतलब है कि भाषा के spec ने 'a-> b' को '(* ए) .b' में फिर से लिखने के लिए कंपाइलर से पूछा है, क्या यह अभी भी' ऑपरेटर *()' को फिर से आमंत्रित करने के लिए समझ में आता है? नहीं, क्योंकि कभी-कभी "अंत तक पहुंचने" से पहले इसे रोकने के लिए जरूरी है (यानी एक पॉइंटर/पॉइंटर-जैसी ऑब्जेक्ट लौटाएं, उदाहरण के लिए, आप इसे अंतिम संशोधित ऑब्जेक्ट को वापस करने के बजाय इसे संशोधित कर सकते हैं)। 'ऑपरेटर ->() 'रिकर्सन अजीबता संभव है (आवश्यक?) क्योंकि यह वास्तव में" उचित "2-Arg ऑपरेटर नहीं है - दूसरा" तर्क "एक' struct' फ़ील्ड नाम होना चाहिए, जो कुछ ऐसा हो सकता है जो ' सी ++ प्रकार प्रणाली में व्यक्त नहीं किया जाएगा। –

+3

पीएस: मैं इसे * सिंटैक्टिक गुड़िया * कहूंगा - मेरी समझ को क्रॉल में धीमा कर रहा हूं ...: पी –

0

आप दूसरी ओर एक चर (पहुँच बढ़ रहा है) या यहां तक ​​कि कुछ सुरक्षा जाँच आदि बढ़ाने की तरह, कुछ अन्य कार्यों क्या करना चाहते हो सकता है, मैं था

-1

मुझे लगता है कि यह boost_ptr <> बढ़ावा में (उदाहरण के लिए) के लिए उपयोग किया जाता है। इससे उन्हें सामान्य पॉइंटर्स की तरह "देखो" मिल जाता है, हालांकि वे विशेष पॉइंटर्स हैं (संदर्भ गिनती संदर्भ)।

+7

यह मुझे कुछ भी दिलचस्प नहीं बताता है मुझे डर है। 'Shared_ptr' को' ऑपरेटर *() 'को अधिभारित करने के बजाय 'ऑपरेटर ->()' को अधिभारित करने की आवश्यकता क्यों है और संकलक को' p-> m' '(* p) .m' में फिर से लिखने दें? इसमें स्थिरता का स्पष्ट लाभ है - आप या तो सिंटैक्स का उपयोग कर सकते हैं और एक ही परिणाम प्राप्त कर सकते हैं, जो निश्चित रूप से सभी को उम्मीद है। तो ऐसा क्यों नहीं किया जाता है? –

+0

@j_random_hacker +1 यह बिल्कुल मेरी बात है! – fredoverflow

3

एक उपयोग के मामले हो सकता है जब आप सी ++ के अंदर एक डीएसएल बना रहे हैं, Boost Karma की तर्ज पर जहां पूरी तरह से पारंपरिक सी ++ ऑपरेटरों का अर्थ बदल (यह, हालांकि उनके पुस्तकालय में -> ओवरलोड प्रतीत नहीं होता है),। चाहे यह एक अच्छा विचार है निश्चित रूप से बहस करने के लिए।

+0

खुद कारण के लिए +1 है, लेकिन यह मेरे लिए एक भयानक विचार जैसा लगता है ... एक प्रतिलिपि ctor लिखने के रूप में बुरा है जो दुनिया की स्थिति को बदलता है (क्योंकि कभी-कभी संकलक इसे कॉल करना चुन सकता है या नहीं)। –

1

नियमित पॉइंटर्स p->m और (*p).m प्रदान करते हैं, p->m के साथ कहीं अधिक आम है। यदि आप केवल उनमें से एक को अधिभारित करने की अनुमति देते हैं, तो यह डिफ़ॉल्ट प्रकार के साथ असंगत होगा। क्यों नहीं, संकलक इसे फिर से लिखने दें, सरल जवाब इसलिए है क्योंकि कभी-कभी, आप ऑपरेटर-> टी * वापस करने के लिए नहीं चाहते हैं, जहां ऑपरेटर * टी & देता है। उन्हें अलग-अलग अधिभारित करने की अनुमति देने से उन संयोजनों की अनुमति मिलती है जिन्हें आप जरूरी नहीं सोच सकते हैं। लेकिन यह मूर्खतापूर्ण होगा, क्योंकि हम वर्तमान में इसे बदलने के किसी भी कारण के बारे में सोच नहीं सकते हैं। जैसा कि आप चाहते थे, उतना ही, आपके पास int128 वर्ग और ओवरलोड ऑपरेटर + = का अर्थ एक्सपोनेंटिएशन होना चाहिए।

+0

मैं इस विचार से सहमत हूं कि कुछ भी मना कर रहा है क्योंकि आप इसे खराब करने की अनुमति देने के अच्छे कारण के बारे में नहीं सोच सकते हैं, इसलिए +1, लेकिन फिर मुझे लगता है कि '->' के ओवरलोडिंग का समर्थन करने वाला कोई भी तर्क '.'' के ओवरलोडिंग का समर्थन करेगा, जो सी ++ अनुमति नहीं देता है आप अधिभार के लिए। –

+0

जरूरी नहीं है। याद रखें कि कम से कम एक ऑपरेटर को गैर-अधिभार योग्य रहना चाहिए, ताकि लोग हर समय बेस क्लास तक पहुंच सकें। – Puppy

+0

मुझे खेद नहीं है - हमेशा बेस क्लास तक पहुंचने में सक्षम होना क्यों महत्वपूर्ण है? इसके अलावा, यह मुझे स्पष्ट नहीं है कि '->' '.' से ओवरलोडिंग के लिए अधिक उपयुक्त क्यों है। –

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

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