2012-11-29 27 views
6

Possible Duplicate:
C++: overriding public\private inheritanceव्युत्पन्न वर्ग

class base { 
public: 
    virtual void doSomething() = 0; 
}; 

class derived : public base { 
private: // <-- Note this is private 

    virtual void doSomething() 
    { cout << "Derived fn" << endl; } 
}; 
अब

में निजी आभासी समारोह अगर मैं निम्नलिखित है:

base *b = new child; 
b->doSomething(); // Calls the derived class function even though that is private 

प्रश्न:

  1. यह व्युत्पन्न वर्ग समारोह कॉल करने के लिए भले ही सक्षम है यह निजी है यह कैसे संभव है?

अब मैं संरक्षित/निजी एक संकलन त्रुटि, मैं पाने के लिए जनता से विरासत पहुँच विनिर्देशक बदलते हैं:

'type cast' : conversion from 'Derived *' to 'base *' exists, but is inaccessible 

नोट: मैं विरासत पहुँच विनिर्देशक की अवधारणाओं के बारे में पता कर रहा हूँ। तो दूसरे मामले में यह निजी/संरक्षित व्युत्पन्न है, यह पहुंच योग्य नहीं है। लेकिन मुझे पहले सवाल के जवाब के बारे में आश्चर्य है। किसी भी इनपुट की अत्यधिक सराहना की जाएगी।

उत्तर

6

एक्सेस नियंत्रण संकलन समय पर लागू होता है, रन-टाइम नहीं, जबकि बहुरूपता (आभासी कार्यों के उपयोग सहित) एक रन-टाइम सुविधा है।

+0

मुझे लगता है कि वह जानना चाहता है कि त्रुटि का स्रोत क्या है, यह जानने के बजाय एक्सेस विनिर्देशक इस तरह से क्यों काम करता है। – Hossein

6

पहले मामले में एक्सेस चेक किया जाता है (जैसा कि यह हमेशा किया जाता है) कॉल के माध्यम से स्थिर प्रकार पर किया जाता है। *b का स्थिर प्रकार base है, और उस स्थिति में doSomething()public है।

सी ++ 03 11.6 "आभासी कार्यों के लिए पहुँच" कहते हैं:

The access rules (clause 11) for a virtual function are determined by its declaration and are not affected by the rules for a function that later overrides it. [Example:

class B { 
public: 
    virtual int f(); 
}; 

class D : public B { 
private: 
    int f(); 
}; 

void f() 
{ 
    D d; 
    B* pb = &d; 
    D* pd = &d; 

    pb->f(); //OK:B::f()is public, 
      // D::f() is invoked 
    pd->f(); //error:D::f()is private 
} 

—end example]

Access is checked at the call point using the type of the expression used to denote the object for which the member function is called (B* in the example above). The access of the member function in the class in which it was defined (D in the example above) is in general not known.

ध्यान रखें विशेष रूप से है कि "वर्ग में सदस्य समारोह का उपयोग कर सकते है जिसमें यह परिभाषित किया गया था (उपरोक्त उदाहरण में डी) सामान्य रूप से ज्ञात नहीं है "। आम तौर पर, आपके उदाहरण में उस बिंदु पर जहां b->doSomething(); कहा जाता है, संकलक को derived (या child) पर कोई ज्ञान नहीं हो सकता है, derived::doSomething() तक पहुंच निजी है या नहीं।

0

निजी कार्यों को बाहरी दुनिया से और व्युत्पन्न कक्षाओं से छुपाया जाना है। यद्यपि आप माता-पिता के DoSomething के एक्सेस विनिर्देश को ओवरराइड कर रहे हैं और इसे निजी बना रहे हैं, फिर भी आप बेस क्लास को तुरंत चालू कर रहे हैं; इसलिए पहले मामले में, आप बेस के डूसमिंग को कॉल कर सकते हैं क्योंकि यह सार्वजनिक है। यदि आप अपनी व्युत्पन्न कक्षा से प्राप्त लोगों को रोकना चाहते हैं तो इस परिदृश्य का उपयोग किया जा सकता है।

दूसरे मामले में, private एक्सेस विनिर्देशक आधार के सदस्यों को व्युत्पन्न वर्ग के उपयोगकर्ताओं के संपर्क में आने का कारण बनता है, जो प्रभावी ढंग से व्युत्पन्न कक्षा को बेकार बनाता है।

+0

ओपी ने काफी स्पष्ट कहा ** यह व्युत्पन्न वर्ग समारोह ** को कॉल करने में सक्षम है। ** के बारे में आपकी अटकलें आप बेस के डूसमिंग को कॉल कर सकते हैं क्योंकि यह सार्वजनिक है ** दिए गए उदाहरण के आधार पर गलत है और प्रश्न 1 पर कोई जवाब नहीं है। – StahlRat

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