2009-03-19 10 views
8

मुझे लाइब्रेरी में निम्न कोड मिला:इस अप्रत्यक्ष फ़ंक्शन कॉल का क्या फायदा है?

class Bar { 
public: 
    bool foo(int i) { 
    return foo_(i); 
    } 
private: 
    virtual bool foo_(int i) = 0; 
}; 

अब मैं सोच रहा हूं: आप इस संकेत का उपयोग क्यों करेंगे? क्या कोई कारण हो सकता है कि उपरोक्त सरल विकल्प से बेहतर क्यों होगा:

class Bar { 
public: 
    virtual bool foo(int i) = 0; 
}; 

उत्तर

10

यह Non-Virtual Interface Idiom (एनवीआई) है। हर्ब सटर द्वारा उस पृष्ठ के बारे में काफी जानकारी है। हालांकि, सी ++ एफएक्यू लाइट क्या कहते हैं, here और here के साथ आप जो पढ़ते हैं उसे गुस्सा करें।

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

स्पष्ट नुकसान यह है कि आपको अतिरिक्त कोड लिखना है। इसके अलावा, private वर्चुअल फ़ंक्शंस बहुत से लोगों को भ्रमित कर रहे हैं। कई कोडर गलती से सोचते हैं कि आप उन्हें ओवरराइड नहीं कर सकते हैं। हर्ब सटर private वर्चुअल की तरह प्रतीत होता है, लेकिन आईएमएचओ सी ++ एफएक्यू लाइट की सिफारिश का पालन करने के लिए अभ्यास में अधिक प्रभावी है और उन्हें protected बनाते हैं।

3

इस बार एक खाका-हुक जोड़ी (हॉटस्पॉट a.k.a) कहा जाता है, वोल्फगैंग प्री द्वारा गढ़ा: वहाँ किसी भी कारण हैं जिनकी वजह से ऊपर सरल विकल्प से बेहतर होगा हो सकता है।

अविवेक करने के लिए इस PDF, PowerPoint, HTML

एक कारण यह देखें के रूप में आप यह है फोन है कि चीजें अक्सर कर सकते हैं/सेटअप पहले एक विधि है, और कुछ cleaing पद एक हो गया है विधि कॉल उपवर्गों में आप केवल सेटअप और सफाई कर के बिना आवश्यक व्यवहार की आपूर्ति करने ...

0

एक उपवर्ग foo_ की परिभाषा को बदल सकता है अगर जरूरत है ?, लेकिन उपभोक्ताओं (कार्यकुशलता के लिए) एक स्थिर समारोह की जरूरत ? या एक प्रतिनिधिमंडल पैटर्न के लिए?

2

यह टेम्पलेट पैटर्न है। Foo विधि में कोड होता है जिसे सभी उप-वर्गों द्वारा निष्पादित किया जाना चाहिए।

class Bar { 
public: 
    bool foo(int i) { 
    // Setup/initialization/error checking/input validation etc 
    // that must be done for all subclasses 
    return foo_(i); 
    } 
private: 
    virtual bool foo_(int i) = 0; 
}; 

यह विकल्प, व्यक्तिगत रूप से प्रत्येक उपवर्ग में आम कोड कॉल करने के लिए याद करने के लिए प्रयास करने के लिए है जो की तुलना में बेहतर होता है: यह अधिक भावना है जब आप इस तरह इस पर गौर करता है। अनिवार्य रूप से, कोई उप-वर्ग बनाता है लेकिन सामान्य कोड को कॉल करना भूल जाता है, जिसके परिणामस्वरूप किसी भी समस्या का सामना करना पड़ता है।

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

  • कोई संबंधित समस्या नहीं^_^