2013-08-07 4 views
35

क्या कोई यह बता सकता है कि सी ++ कंपाइलर्स वर्चुअल फ़ंक्शंस के पैरामीटर के लिए डिफ़ॉल्ट मान कहां रखते हैं? मुझे पता है कि इन वर्गों को बाल वर्गों में बदलने का बुरा विचार है, लेकिन क्यों? धन्यवाद।वर्चुअल फ़ंक्शंस डिफ़ॉल्ट पैरामीटर

+1

आप किसी भी उदाहरण कोड है देखें? –

उत्तर

51

यह एक बुरा विचार है क्योंकि उन्हें कहीं भी नहीं रखा जाता है।

उपयोग किए जाने वाले डिफ़ॉल्ट मान स्थिर (संकलित-समय) प्रकार में परिभाषित किए जाएंगे। तो यदि आप ओवरराइड में डिफ़ॉल्ट पैरामीटर को बदलना चाहते थे, लेकिन आपने बेस क्लास पॉइंटर या संदर्भ के माध्यम से फ़ंक्शन को कॉल किया था, तो बेस में डिफ़ॉल्ट मान का उपयोग किया जाएगा।

#include <iostream> 

struct Base 
{ 
    virtual ~Base(){ } 
    virtual void foo(int a=0) { std::cout << "base: " << a << std::endl; } 
}; 

struct Derived : public Base 
{ 
    virtual ~Derived() { } 
    virtual void foo(int a=1) { std::cout << "derived: " << a << std::endl; } 
}; 

int main() 
{ 
    Base* derived = new Derived(); 
    derived->foo(); // prints "derived: 0" 
    delete derived; 
} 
+9

यह समझने के लिए कि यह कैसे काम करता है, डिफ़ॉल्ट मान कॉल साइट पर भर जाता है (जहां केवल स्थिर प्रकार ज्ञात है) इसलिए संकलक वास्तव में 'व्युत्पन्न-> foo()' को 'व्युत्पन्न-> foo (0)' में अनुवादित करता है समय संकलित करें। –

5

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

निम्नलिखित गैर अनुरूप कोड

class Thing { 
    public: 
    virtual ~Thing(); 
    virtual void doItNTimes(int numTimes = 10); 
    virtual void doItThisHigh(double howHigh = 1.0); 
    // ... 
}; 
class MyThing : public Thing { 
    public: 
    void doItNTimes(int numTimes); 
    void doItThisHigh(double howHigh = 2.2); 
    // ... 
}; 

एक डिफ़ॉल्ट प्रारंभकर्ता एक समारोह हस्ताक्षर के प्रकार का हिस्सा नहीं है और अधिभावी या छुपा में भाग नहीं लेता पर विचार करें। इसलिए इस गैर-अनुपालन कोड उदाहरण में दिखाए गए बेस क्लास वर्चुअल फ़ंक्शंस दोनों व्युत्पन्न कक्षा में ओवरराइड हैं। हालांकि, बेस क्लास और व्युत्पन्न कक्षा इंटरफेस में डिफ़ॉल्ट तर्क प्रारंभकर्ताओं की स्थिति में मतभेद किसी ऑब्जेक्ट तक पहुंचने के लिए किस इंटरफ़ेस का उपयोग किया जाता है, इस पर निर्भर करता है कि व्यवहार में भिन्नताएं होती हैं।

MyThing *mt = new MyThing; 
Thing *t = mt; 
t->doItNTimes(); // default of 10 
mt->doItNTimes(); // compile time error! 
t->doItThisHigh(); // default of 1.0! 
mt->doItThisHigh(); // default of 2.2 

कोड के इस टुकड़े में, MyThing वर्ग के डिजाइनर के इरादे स्पष्ट नहीं है। संभवतः, यह महत्वपूर्ण है कि MyThing प्रकार के ऑब्जेक्ट के लिए iItThisHigh करने का डिफ़ॉल्ट मान 2.2 हो। हालांकि, यह स्पष्ट नहीं है कि उस मान को डिफ़ॉल्ट रूप से भी उपयोग किया जाना चाहिए जब माईटिंग को अपने थिंग इंटरफ़ेस के माध्यम से छेड़छाड़ की जाती है।

अधिक जानकारी के लिए नीचे दिए गए लिंक https://www.securecoding.cert.org/confluence/display/cplusplus/OOP04-CPP.+Prefer+not+to+give+virtual+functions+default+argument+initializers

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