मुझे आभासी कार्यों को अधिभारित करने की आवश्यकता क्यों है?
मैं दो अतिभारित कार्यों के साथ एक आधार वर्ग है f(void)और f(int)। कक्षा बुलाकर Derivedलागू करती f(int)है f(void)। केवल Derived2लागू f(void)करता है।
संकलक कार्यान्वयन को अस्वीकार कर देता है Derived::f(int)क्योंकि यह कॉल करना चाहता है f(int)लेकिन मैंने कोई तर्क नहीं दिया क्योंकि मैं कॉल करना चाहता हूं f(void)। संकलक इसे अस्वीकार क्यों करता है? लाइन जोड़ने से virtual int f(void) = 0;मेरी समस्या ठीक क्यों होती है?
class Base
{
public:
explicit Base(void) {}
virtual ~Base(void) {}
virtual int f(void) = 0;
virtual int f(int i) = 0;
};
class Derived : public Base
{
public:
// provide implementation for f(int) which uses f(void). Does not compile.
virtual int f(int i) {puts("Derived::f(int)"); return f();}
// code only compiles by adding the following line.
virtual int f(void) = 0;
};
class Derived2 : public Derived
{
public:
// overwrite only f(void). f(int) is implemented by Derived.
virtual int f(void) {puts("Derived2::f(void)"); return 4;}
};
int main(void)
{
Base * p = new Derived2();
int i0 = p->f(); // outputs Derived2::f(void) and returns 4
int i1 = p->f(1); // outputs "Derived::f(int) Derived2::f(void)" and return 4
delete p;
return 0;
}
जवाब
Derived::fछुपाता है Base::f। return f();के शरीर में देखते हुए Derived::f(int), नाम fके दायरे में पाया जाता है Derived, फिर नाम खोज बंद हो जाता है। नाम Baseनहीं मिलेंगे और अधिभार संकल्प में भाग लेंगे।
नाम लुकअप नीचे बताए अनुसार स्कोप्स की जांच करता है, जब तक कि यह किसी भी प्रकार की कम से कम एक घोषणा नहीं पाता है, जिस समय लुकअप बंद हो जाता है और आगे के स्कोप की जांच नहीं की जाती है।
आप के दायरे में using Base::f;से नाम जोड़ने के लिए जोड़ सकते हैं ।BaseDerived
class Derived : public Base
{
public:
using Base::f;
// provide implementation for f(int) which uses f(void).
virtual int f(int i) {puts("Derived::f(int)"); return f();}
};