विषय में प्रश्न एक बहुत ही सामान्य भ्रम का सुझाव देता है। यह भ्रम काफी आम है, कि C ++ FAQ ने लंबे समय तक निजी वर्चुअल का उपयोग करने की वकालत की, क्योंकि भ्रम एक बुरी चीज थी।
तो पहले भ्रम से छुटकारा पाने के लिए: हाँ, निजी आभासी कार्यों को व्युत्पन्न कक्षाओं में ओवरराइड किया जा सकता है। व्युत्पन्न वर्गों के तरीके आधार वर्ग से आभासी कार्यों को नहीं बुला सकते हैं, लेकिन वे उनके लिए अपना कार्यान्वयन प्रदान कर सकते हैं। हर्ब सटर के अनुसार, बेस क्लास में सार्वजनिक गैर-आभासी इंटरफ़ेस और एक निजी कार्यान्वयन जिसे व्युत्पन्न कक्षाओं में अनुकूलित किया जा सकता है, "बेहतर कार्यान्वयन के विनिर्देशन के विनिर्देश से इंटरफ़ेस के विनिर्देशन को अलग करने" की अनुमति देता है। आप इसके बारे में उनके लेख "आभासीता" में अधिक पढ़ सकते हैं ।
हालांकि आपके द्वारा प्रस्तुत कोड में एक और दिलचस्प बात है, जो मेरी राय में कुछ और ध्यान देने योग्य है। सार्वजनिक इंटरफ़ेस में ओवरलोड गैर-वर्चुअल फ़ंक्शंस का एक सेट होता है और वे फ़ंक्शंस ग़ैर-सार्वजनिक, गैर-अतिभारित वर्चुअल फ़ंक्शंस कहते हैं। सी ++ दुनिया में हमेशा की तरह यह एक मुहावरा है, इसका एक नाम है और निश्चित रूप से यह उपयोगी है। नाम है (आश्चर्य, आश्चर्य!)
"सार्वजनिक अतिभारित गैर-आभासी कॉल संरक्षित गैर-अतिभारित आभासी"
यह छिपने के नियम को ठीक से प्रबंधित करने में मदद करता है । आप इसके बारे में यहाँ और अधिक पढ़ सकते हैं , लेकिन मैं इसे शीघ्र ही समझाने की कोशिश करूँगा।
कल्पना कीजिए, Engine
वर्ग के आभासी कार्य भी इसका इंटरफ़ेस हैं और यह अतिभारित कार्यों का एक समूह है जो शुद्ध आभासी नहीं है। यदि वे शुद्ध आभासी थे, तो एक ही समस्या का सामना कर सकता है, जैसा कि नीचे वर्णित है, लेकिन वर्ग पदानुक्रम में कम है।
class Engine
{
public:
virtual void SetState( int var, bool val ) {/*some implementation*/}
virtual void SetState( int var, int val ) {/*some implementation*/}
};
अब मान लेते हैं कि आप एक व्युत्पन्न वर्ग बनाना चाहते हैं और आपको केवल विधि के लिए एक नया कार्यान्वयन प्रदान करने की आवश्यकता है, जो तर्क के रूप में दो ints लेता है।
class MyTurbochargedV8 : public Engine
{
public:
// To prevent SetState( int var, bool val ) from the base class,
// from being hidden by the new implementation of the other overload (below),
// you have to put using declaration in the derived class
using Engine::SetState;
void SetState( int var, int val ) {/*new implementation*/}
};
यदि आप व्युत्पन्न घोषणा को व्युत्पन्न वर्ग में रखना भूल गए (या दूसरे अधिभार को फिर से परिभाषित करने के लिए), तो आप नीचे के परिदृश्य में परेशानी में पड़ सकते हैं।
MyTurbochargedV8* myV8 = new MyTurbochargedV8();
myV8->SetState(5, true);
यदि आप Engine
सदस्यों को छिपाने से नहीं रोकते हैं, तो कथन:
myV8->SetState(5, true);
void SetState( int var, int val )
व्युत्पन्न वर्ग से कॉल करने के true
लिए परिवर्तित होगा int
।
यदि इंटरफ़ेस आभासी नहीं है और आभासी कार्यान्वयन गैर-सार्वजनिक है, जैसे आपके निर्वासन में, व्युत्पन्न वर्ग के लेखक के पास सोचने के लिए एक कम समस्या है और बस लिख सकते हैं
class MyTurbochargedV8 : public Engine
{
private:
void SetStateInt(int var, int val ) {/*new implementation*/}
};