2011-06-05 25 views
9

यह सिर्फ एक प्रयोग कोड है।वर्चुअल ऑपरेटर ओवरलोडिंग ->()

struct B 
{ 
    virtual B* operator ->() { return this; } 
    void foo() {} // edit: intentionally NOT virtual 
}; 

struct D : B 
{ 
    virtual D* operator ->() { return this; } 
    void foo() {} 
}; 

int main() 
{ 
    B &pB = *new D; 
    pB->foo(); // calls B::foo() ! 
} 

मुझे पता है कि operator वस्तु या संदर्भ का उपयोग कर के नाम से जाना पड़ता है; इस प्रकार उपर्युक्त मामले में संदर्भ pB अभी भी B की ऑब्जेक्ट पर दृढ़ संकल्प करता है? हालांकि यह व्यावहारिक नहीं होगा, लेकिन जिज्ञासा के लिए, क्या D::operator ->pB के माध्यम से आमंत्रित करने का कोई तरीका है?

+0

ऑपरेटर-> आभासी होने के लिए समझ में नहीं आता है जब आप foo() वर्चुअल होना चाहते हैं। –

+0

मुझे यहां कुछ याद आ रहा है, लेकिन 'void foo()' वर्चुअल बनाने में क्या गलत है? 'ऑपरेटर ->()' इस स्थिति में पूरी तरह से व्यर्थ है, खासकर जब से यह 'यह' देता है। –

+0

@ सिलिको में, मैं मानता हूं, यह जानने के लिए यह एक प्रयोग कोड है कि क्या होता है जब ऑपरेटर -> 'वर्चुअल 'बन जाता है। मैंने अपना प्रश्न संपादित किया है। धन्यवाद। – iammilind

उत्तर

8

मुझे लगता है कि यह D::operator-> लागू है, लेकिन वापसी मान तो B::foo() बुलाया जा रहा है एक B* के रूप में इलाज किया जा रहा है,।

यह कॉन्वर्सट रिटर्न प्रकार व्यवहार का एक आर्टिफैक्ट है।

1

इससे कोई फ़र्क नहीं पड़ता कि यह कौन सा ऑपरेटर आमंत्रित करता है (जो इस मामले में शायद D::operator-> है), this क्या मायने रखता है। इस मामले में this सूचक B* प्रकार का है, इसलिए foo कॉल को B::foo पर अस्वीकार कर दिया गया है। यदि यह virtual था - इसे सही ढंग से काम करेगा, लेकिन आप जानबूझकर यह virtual नहीं किया ...

+0

+1, यह निश्चित रूप से 'डी :: ऑपरेटर->' (संभवतः नहीं)। – iammilind

2

pB प्रकार B& की है। इसलिए operator->) पर किसी भी विधि (operator->) पर हस्ताक्षर किए जाएंगे, B में हस्ताक्षर प्राप्त होगा, इसलिए pB.operator->()B* लौटाएगा। बेशक, क्योंकि यह आभासी है, D में वास्तविक कार्यान्वयन का उपयोग किया जाता है। महत्वपूर्ण बात यह है कि वापसी प्रकार पीबी चर के प्रकार से परिभाषित किया जाता है।

तो, हमारे operator-> ने B* वापस कर दिया है, और इसलिए foo() किसी भी अन्य B* के साथ आय का आह्वान किया है।

+0

यह उत्तर नया नहीं है, लेकिन मैंने सोचा कि यह तर्क पर थोड़ा आगे विस्तार करने की कोशिश करने के लिए उपयोगी हो सकता है। –

1

वर्चुअल सदस्य फ़ंक्शंस कॉल में प्रयुक्त ऑब्जेक्ट के डायनामिक के अनुसार लागू किए जाते हैं। गैर वर्चुअल सदस्य फ़ंक्शंस को कॉल में प्रयुक्त ऑब्जेक्ट के स्थिर के अनुसार लागू किया जाता है।

फ़ंक्शन foo वर्चुअल नहीं है। इसका मतलब है कि इसे हमेशा स्थिर ऑब्जेक्ट के प्रकार के अनुसार बुलाया जाता है। इस मामले में स्थिर प्रकार B है (क्योंकि B::operator -> के परिणाम घोषित प्रकार B * है), इसलिए B::foo कहा जाता है।

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