2013-04-05 14 views
5

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

अर्थात

class Base 
{ 
public: 
Base(); 
virtual ~Base(); 
virtual void foo(int,double)=0; 
}; 

class Derived: 
public Base 
{ 
private: 
    // methods 
public: 
Derived(); 
virtual ~Derived(); 
virtual void foo(int, double, double); //this doesn't work 
}; 

एक समाधान हो सकता है:

virtual void foo(int,double,double=0)=0; 
आधार वर्ग में

लेकिन यह बहुत सीमित है। तुम क्या सोचते हो?

+1

फ़ंक्शन ओवरलोड एक ** अलग API ** का प्रतिनिधित्व करते हैं। एक सार आधार वर्ग ** ** लगातार API ** का प्रतिनिधित्व करता है। तो नहीं, यह समझ में नहीं आता है। –

+0

क्या आपका उदाहरण 'क्लास व्युत्पन्न: बेस' गायब नहीं है? – nonsensickle

+0

@ गैरकानूनी: ठीक है, मैंने अभी संपादित किया है। धन्यवाद – Ale

उत्तर

9

ये 2 कार्य अलग हैं। उत्तरार्द्ध पहले

virtual void foo(int,double)=0; 
virtual void foo(int, double, double); 

दूसरा दूसरा व्युत्पन्न करने के लिए विशिष्ट नया वर्चुअल फ़ंक्शन ओवरराइड नहीं कर रहा है।

यदि आप अंत में override डालते हैं तो संकलन शिकायत करेगा कि आप कुछ भी ओवरराइड नहीं कर रहे हैं। हालांकि यह सी ++ 11 चेक है।

virtual void foo(int, double, double) override; 

उपयोगकर्ता सत्यापित करने के लिए समारोह के अंत में उपयोग override पुष्टि करने के लिए एक शुद्ध आभासी समारोह ओवरराइड कर सकते हैं। आपके मामले में दूसरा फ़ंक्शन केवल व्युत्पन्न सूचक या प्रकार का उपयोग करके एक्सेस किया जा सकता है। (हालांकि इसे तब तक तत्काल नहीं किया जा सकता जब तक शुद्ध वर्चुअल फ़ंक्शन ठीक से ओवरराइड और लागू नहीं किया जाता है, तब तक यह एक सार वर्ग नहीं है)। इसलिए यदि Derived से प्राप्त कक्षाओं द्वारा आगे बढ़ने का इरादा नहीं है, तो इसे वर्चुअल बनाना एक ओवरहेड है क्योंकि वैसे भी यह मूल विधि को ओवरराइड नहीं कर रहा है।

+0

जब मैं यह उत्तर पॉप अप करता था तो मैं सिर्फ 'ओवरराइड' के बारे में लिख रहा था। तो यहां कम से कम लिंक जाता है: http://msdn.microsoft.com/en-us/library/vstudio/jj678987.aspx – Kupto

+0

@ कूपो: उदाहरण में, पहली बार funcC (double = 0.0) ओवरराइड काम करता है जबकि दूसरा कोड यह काम नहीं करता है? – Ale

+0

@Ale मैंने अभी कोशिश की है और ऐसा लगता है कि टिप्पणियों को ध्यान में रखते हुए, पहले उदाहरण में 'ओवरराइड' कीवर्ड अनावश्यक है। – Kupto

4

आप नहीं कर सकते।

मान लें कि आपके पास Base पॉइंटर है, जो Derived ऑब्जेक्ट पर इंगित करता है। Base सूचक होने के बाद, आपके पास केवल Base के इंटरफ़ेस तक "पहुंच" है (जब तक आप Derived पॉइंटर पर नहीं जाते हैं, लेकिन यह आपको आवश्यक नहीं है)।

+0

हाँ, यह एक समस्या है। तो एकमात्र समाधान एक अमूर्त वर्ग बना रहा है लेकिन इंटरफ़ेस नहीं है। यही है ना – Ale

+0

@Ale - मुझे आपका अंक नहीं मिला। सी ++ में 'इंटरफेस' और 'अमूर्त वर्ग' के बीच क्या अंतर है? –

+0

[लिंक] (http://stackoverflow.com/questions/15387581/more-methods-in-derived-classes-than-base-class), एक व्युत्पन्न वर्ग में अमूर्त वर्ग की तुलना में अधिक कार्य हो सकते हैं। इसके बजाय एक इंटरफ़ेस विधियों की संख्या (मेरी राय में) को सीमित करता है। – Ale

3

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

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

0

जैसा कि दूसरों द्वारा इंगित किया गया है, यह अभी काम नहीं करेगा।

अधिक कड़ाई से, यहाँ क्या होता है

Derived d; 
d.foo(5, 10.0); // Works as expected 

Base &b = d; // b is polymorphic 
b.foo(3,10,4); // foo(int, double, double) is not in class Base, hence compile-time resolution fails! 
0

यह अधिभावी नहीं है के रूप में समारोह हस्ताक्षर भिन्न हैं।पॉलिमॉर्फिज्म नियम के अनुसार एक समारोह को ओवरराइड करने के लिए फ़ंक्शन हस्ताक्षर और प्रकार समान होना चाहिए।

इस मामले में ये कार्य अलग हैं। वर्चुअल शून्य फू (int, double) = 0; आभासी शून्य फू (int, डबल, डबल);

0

बेस क्लास में foo ओवरलोडिंग सबसे आसान समाधान नहीं है?

class Base 
{ 
public: 
Base(); 
virtual ~Base(); 
virtual void foo(int,double)=0; 
virtual void foo(int,double,double)=0; 
}; 
संबंधित मुद्दे