2012-06-03 28 views
7

से डिफ़ॉल्ट पैरामीटर प्राप्त करता है क्या कोई बता सकता है कि नीचे दिए गए कोड का परिणाम "कक्षा बी :: 1" क्यों होगा?कोड व्युत्पन्न क्लास विधि निष्पादित करता है, लेकिन बेस क्लास विधि

व्युत्पन्न वर्ग की वर्चुअल विधि बेस क्लास के डिफ़ॉल्ट पैरामीटर का उपयोग क्यों करती है, न कि स्वयं? मेरे लिए यह बहुत अजीब है। अग्रिम में धन्यवाद!

कोड:

#include <iostream> 

using namespace std; 

class A 
{ 
public: 
    virtual void func(int a = 1) 
    { 
     cout << "class A::" << a; 
    } 
}; 

class B : public A 
{ 
public: 
    virtual void func(int a = 2) 
    { 
     cout << "class B::" << a; 
    } 
}; 

int main() 
{ 
    A * a = new B; 
    a->func(); 

    return 0; 
} 

उत्तर

6

क्योंकि डिफ़ॉल्ट तर्क स्थिर प्रकार के अनुसार हल किए जाते हैं this (यानी, वेरिएबल का प्रकार, जैसे A&A& a; में)। ideone पर

class B::1 
class B::2 

कार्रवाई में:

थोड़ा अपने उदाहरण में संशोधन:

#include <iostream> 

class A 
{ 
public: 
    virtual void func(int a = 1) 
    { 
     std::cout << "class A::" << a << "\n"; 
    } 
}; 

class B : public A 
{ 
public: 
    virtual void func(int a = 2) 
    { 
     std::cout << "class B::" << a << "\n"; 
    } 
}; 

void func(A& a) { a.func(); } 

int main() 
{ 
    B b; 
    func(b); 
    b.func(); 

    return 0; 
} 

हम निम्नलिखित उत्पादन का निरीक्षण।

यह अनुशंसा नहीं की जाती है कि वर्चुअल फ़ंक्शन इस कारण से डिफ़ॉल्ट मान बदलता है। दुर्भाग्यवश मुझे इस कंस्ट्रक्शन पर चेतावनी देने वाले किसी भी कंपाइलर को नहीं पता है।

  • एक नया कार्य ट्रैम्पोलिन के रूप में कार्य करने के लिए बनाने के लिए::


    तकनीकी व्याख्या वहाँ डिफ़ॉल्ट तर्क के साथ काम करने के दो तरीके हैं कि है void A::func() { func(1); }

  • ऐड-इन कॉल पर याद आ रही तर्क साइट a.func() =>a.func(/*magic*/1)

अगर यह पूर्व थे (और यह सोचते हैं कि A::func w जैसा कि virtual घोषित किया गया है), तो यह आपकी अपेक्षा की तरह काम करेगा। हालांकि बाद का फॉर्म निर्वाचित किया गया था, या तो virtual के साथ समस्या उस समय पूर्ववत नहीं थी या क्योंकि उन्हें लाभ (यदि कोई हो ...) के विपरीत अपरिहार्य माना जाता था।

5

क्योंकि डिफ़ॉल्ट मान संकलन के दौरान दिया जाता है और, जबकि असली समारोह (ए :: समारोह या बी :: समारोह) के नाम से जाना रनटाइम पर निर्धारित किया जाता है घोषणा से लिया जाता है।

+0

तेज़ उत्तर के लिए धन्यवाद! – Aremyst

5

क्योंकि सी ++ में बहुलकता रन-टाइम पर प्रभावी होती है, जबकि डिफ़ॉल्ट पैरामीटर का प्रतिस्थापन संकलन-समय पर प्रभावी होता है। संकलन समय पर, कंपाइलर उस वस्तु के गतिशील प्रकार को नहीं जानता (और यह नहीं जानता है) जिस पर पॉइंटर a अंक। इसलिए, यह केवल a के लिए जानता है, जो कि आपके उदाहरण में A * है, के लिए डिफ़ॉल्ट तर्क लेता है।

(यह संयोग से भी कारण डिफ़ॉल्ट पैरामीटर बल्कि कार्यान्वयन/परिभाषाओं में से इंटरफेस/हेडर में दिया जाता है है। संकलक कार्यान्वयन की मशीन कोड में डिफ़ॉल्ट पैरामीटर सम्मिलित करता है कभी नहीं है, लेकिन केवल फोन करने वाले का मशीन कोड में। तकनीकी तौर पर , डिफ़ॉल्ट पैरामीटर कॉलर की संपत्ति है; और कॉलर को पता नहीं है - और किसी वस्तु के गतिशील प्रकार को जानने की आवश्यकता नहीं है।)

+0

आपका उत्तर बहुत स्पष्ट है, धन्यवाद! – Aremyst