2011-12-29 13 views
5

मुझे बताया गया है कि नीचे दिए गए कोड नमूने में बेस क्लास में void operator()(int) की घोषणा क्यों दिखाई दे रही है जब व्युत्पन्न कक्षा void operator()(int,int,int) लागू करती है। व्युत्पन्न कक्षा bar में दृश्यमान होने के लिए मुझे बेस क्लास foo से ऑपरेटर() (int) की घोषणा कैसे प्राप्त हो सकती है? यही है, मैं उदाहरण को कैसे संशोधित कर सकता हूं ताकि ऑपरेटर() (int) का आमंत्रण काम करता हो?ऑपरेटर की विरासत()

#include <iostream> 

struct foo 
{ 
     void operator()(int) 
     { 
       std::cout << "A" << std::endl; 
     } 
}; 

struct bar : foo 
{ 
     // If this is uncommented, the code will not compile. 
     // void operator()(int, int, int) {} 
}; 

int main() 
{ 
     bar b; 
     b(1); 
     return 0; 
} 

चिह्नित लाइनों uncommented साथ जब जी के साथ संकलित ++, त्रुटि संदेश के लिए "की कॉल के लिए कोई मुकाबला नहीं पंक्तियों के साथ है 'बार (int)' ... उम्मीदवार शून्य बार है :: ऑपरेटर() (int, int, int) ... उम्मीदवार को 3 तर्क, 1 प्रदान किया जाता है। "

उत्तर

6

यह सही है। व्युत्पन्न वर्ग कार्य ओवरलोडिंग के बजाय बेस क्लास फ़ंक्शन छुपाते हैं। फिक्स बहुत आसान है हालांकि:

struct bar : foo 
{ 
    using foo::operator(); 
    void operator()(int, int, int) {} 
}; 
+0

उत्तर के लिए धन्यवाद! क्या आप कृपया बता सकते हैं कि इस मामले में उपयोग घोषणा क्यों जरूरी है? मैं नहीं देखता कि कैसे घोषित ऑपरेटर() (int, int, int) बेस क्लास में ऑपरेटर() (int) की घोषणा ग्रहण करना चाहिए। उपयोग करने वाले कीवर्ड को निर्दिष्ट करने के लिए थोड़ा बोझिल है, क्योंकि वास्तविक दुनिया परिदृश्य में, मुझे इसे प्रत्येक बेस क्लास में जोड़ना होगा। –

+4

क्यों? क्योंकि मानक ऐसा कहता है। "एक नाम किसी नेस्टेड घोषणात्मक क्षेत्र या व्युत्पन्न वर्ग में उसी नाम की स्पष्ट घोषणा द्वारा छुपाया जा सकता है।" यह भी देखें: http://www2.research.att.com/~bs/bs_faq2.html#overloadderived –

+0

वास्तव में, वर्चुअल फ़ंक्शंस के ओवरराइड बेस क्लास फ़ंक्शंस को भी छुपाते हैं। यह विशेष रूप से परेशान होता है जब बेस क्लास में कई सार्वजनिक वर्चुअल फ़ंक्शंस होते हैं जो समान नाम के ओवरलोड होते हैं: जब उनमें से केवल एक को ओवरराइड करते हैं तो बाकी सभी छिपाए जाते हैं! यह एक कारण है कि मानक सी ++ लाइब्रेरी में कोई सार्वजनिक वर्चुअल फ़ंक्शन नहीं है (विनाशकों को छोड़कर जिन्हें किसी भी तरह अधिभारित नहीं किया जा सकता है और वैसे भी ओवरराइडिंग के संबंध में कुछ अलग काम करता है)। इसके बजाए, सार्वजनिक कार्य प्रतिनिधि संरक्षित (वे वास्तव में निजी होना चाहिए) वर्चुअल फ़ंक्शंस। –

2

ध्यान दें कि ऑपरेटर() यह दिखने से अधिक भ्रमित कर सकता है। क्लासिक उदाहरण शायद बार :: mymethod (int) और foo :: mymethod() जैसे कुछ और होगा। व्युत्पन्न विधि विरासत विधि को छुपाती है क्योंकि संकल्प कैसे होता है। किसी अन्य उत्तर में उपयोग की जाने वाली घोषणा घोषणा संकल्प के लिए foo की विधि में लाती है।

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