2009-02-25 18 views
30

अगर मैं इस तरह एक कोड है पर अधिभार:सी ++ सदस्य समारोह आभासी ओवरराइड और एक ही समय

struct A { 
    virtual void f(int) {} 
    virtual void f(void*) {} 
}; 

struct B : public A { 
    void f(int) {} 
}; 

struct C : public B { 
    void f(void*) {} 
}; 


int main() { 
    C c; 
    c.f(1); 

    return 0; 
} 

मैं एक त्रुटि है कि का कहना है कि मैं शून्य करने के लिए पूर्णांक से अवैध रूपांतरण करने के लिए कोशिश कर रहा हूँ * मिलता है। कंपाइलर क्यों नहीं समझ सकता कि उसे बी :: एफ को कॉल करना है, क्योंकि दोनों कार्यों को वर्चुअल के रूप में घोषित किया गया है?


आधा जवाब पढ़ने के बाद मैं गया और इसे और भी कम कर दिया। यह भी काम नहीं करता है। बहुत सहज नहीं है।

struct A { 
    virtual void f(int) {} 
}; 

struct B : public A { 
    void f(void*) {} 
}; 


int main() { 
    B b; 
    b.f(1); 

    return 0; 
} 

उत्तर

44

संक्षिप्त उत्तर "क्योंकि इस तरह अधिभार संकल्प सी ++ में काम करता है"।

कार्यों एफ सी क्लास के अंदर के लिए संकलक खोज करता है, और अगर यह किसी भी पाता है, यह खोज बंद हो जाता है, और उन लोगों के बीच एक उम्मीदवार लेने के लिए कोशिश करता है। व्युत्पन्न कक्षा में कोई मिलान कार्य नहीं मिलने पर यह केवल बेस क्लास के अंदर दिखता है।

हालांकि, आप स्पष्ट रूप से व्युत्पन्न वर्ग 'नाम स्थान में आधार वर्ग कार्यों को लागू कर सकते हैं:

struct C : public B { 
    void f(void*) {} 
    using B::f; // Add B's f function to C's namespace, allowing it to participate in overload resolution 
}; 
+3

सकता समारोह छिपने पर सी ++ पूछे जाने वाले प्रश्न के लिए एक लिंक जोड़ना चाहते हैं: http://www.parashift.com/c++-faq-lite/strange- inheritance.html # faq-23.9 – greyfade

+0

@jalf: ऐसे कंपाइलर के व्यवहार का कारण क्या है? कॉल फिट करने के लिए फ़ंक्शंस के लिए बेस क्लास क्यों न खोजें? – Andrew

+0

* * * का कारण क्या होगा? कंपाइलर को कुछ व्यवहार चुनना पड़ता है, और यह कुछ मामलों में समझ में आता है, और दूसरों में बेतुका लगता है। इस योजना का लाभ यह है कि आप "खोज जारी रखें" व्यवहार में ऑप्ट-इन कर सकते हैं। लेकिन अगर ऐसा होता तो इसका चयन करने और * यह * व्यवहार प्राप्त करने का कोई तरीका नहीं होगा। दिन के अंत में, भाषा डिजाइनरों को निर्णय लेना पड़ा, और उन्होंने इस व्यवहार को उठाया। :) – jalf

-6

खैर मैं सब से पहले लगता है कि आप समझ में नहीं आया कि क्या आभासी तंत्र या polymorhism। जब पॉलीमोर्फिज्म केवल ऑब्जेक्ट पॉइंटर्स का उपयोग करके हासिल किया जाता है। मुझे लगता है कि आप सी ++ के लिए नए हैं। ऑब्जेक्ट पॉइंटर्स का उपयोग किए बिना पॉलिमॉर्फिज्म या आभासी कीवर्ड का उपयोग बेस क्लास पॉइंटर का कोई अर्थ नहीं है और वांछित व्युत्पन्न क्लास ऑब्जेक्ट्स को असाइन करें। फिर कॉल करें और कोशिश करें।

-1

या आप ऐसा कर सकता है:

void main() 
{ 
    A *a = new C(); 
    a->f(1); //This will call f(int) from B(Polymorphism) 
} 
संबंधित मुद्दे