2012-03-19 19 views
16

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

हालांकि, शुद्ध आभासी के साथ, कोई आधार कार्यान्वयन नहीं है ... तो क्या यह एक निजी आभासी घोषित करने के लिए कार्यात्मक रूप से समान नहीं है या तो निजी या संरक्षित है? एक संरक्षित शुद्ध आभासी समझ में नहीं आता है क्योंकि आप कभी भी बेस क्लास की इसी विधि को नहीं बुला सकते हैं। क्या कोई परिदृश्य है जहां एक संरक्षित शुद्ध आभासी कोई समझ में आता है?

SO पर कुछ समान विषय हैं, लेकिन मुझे कुछ भी नहीं मिला जो मेरे प्रश्न का संक्षेप में उत्तर दिया।

+0

आप इंटरफेस के लिए 'मित्र' को लागू कर सकते हैं। – Matthew

+6

शुद्ध आभासी विधि में शरीर हो सकता है और इसे आधार :: foo() की तरह स्पष्ट रूप से बुलाया जा सकता है। उदाहरण के लिए – iammilind

उत्तर

8

क्या कोई परिदृश्य है जहां संरक्षित शुद्ध वर्चुअल समझ में आता है?

मुझे लगता है कि आपका यहां निजी (सुरक्षित की बजाय) का मतलब है, लेकिन लगता है कि मैं आपकी बात समझता हूं। वास्तव में, शुद्ध वर्चुअल का एक्सेस प्रकार व्युत्पन्न कक्षाओं में ओवरराइड किया जा सकता है। यहां एक उदाहरण के बीच अंतर देखना मदद कर सकता है कि एक निजी और संरक्षित शुद्ध आभासी:

class Parent 
{ 
    protected: virtual void foo() = 0; 
    private: virtual void bar() = 0; 
    public:   void test() { foo(); bar(); } 
}; 

class Child : public Parent 
{ 
    public: void test2() { foo(); /* bar(); // cannot be called here */ } 
}; 

class GrandChild : public Child 
{ 
    // access types here can be anything for this example 
    public: void foo() { cout << "foo" << endl; } 
    public: void bar() { cout << "bar" << endl; } 
}; 
+0

धन्यवाद। बस स्पष्ट करने के लिए - एक निजी शुद्ध वर्चुअल को इसके किसी भी वंशज द्वारा कभी नहीं बुलाया जा सकता है (लेकिन उनके द्वारा कार्यान्वित किया जा सकता है, इसलिए बेस क्लास अपने वंशज की विधि का आह्वान कर सकता है?) – Prismatic

+0

नहीं। इस उदाहरण में, यदि ग्रैंड चाइल्ड को 'foo' कहा जाता है () 'इसके किसी अन्य तरीके के अंदर, यह संकलित और अपेक्षित काम करेगा,' ग्रैंड चाइल्ड :: foo' कहा जाएगा। – mfontanini

+2

हां प्रिस, वर्चुअल फ़ंक्शन को एक अलग एक्सेस प्रकार से ओवरराइड किया जा सकता है जो इसकी पहुंच को खोल सकता है। – LiquidAsh

4

सबसे पहले शुद्ध आभासी समारोह लागू किया जा सकता!

#include <iostream> 

class Animal 
{ 
public: 
    void eat(void); 
protected: 
    virtual void doEat(void)=0; 
}; 
void Animal::eat(void) 
{ 
    doEat(); 
} 
void Animal::doEat(void) 
{ 
    std::cout << "animal" << std::endl; 
} 

class Tiger : public Animal 
{ 
private: 
    virtual void doEat(void) 
    { 
    Animal::doEat();//here is the difference between protected and private 
    std::cout << "tiger" << std::endl; 
    } 
}; 

int main(void) 
{ 
    Animal *p = new Tiger(); 
    p->eat(); 
    return 0; 
} 

दूसरा, हर्ब Sutter समझाया जब उपयोग करने के लिए "वर्चुअल प्राइवेट" या "आभासी संरक्षित", तो आप इस article से पढ़ सकते हैं मैं इस बताता है कि क्यों हम ऐसा नहीं केवल हम कर सकते हैं लेख का कहना है लगता है: " आभासी कार्यों को निजी बनाना पसंद करें, केवल तभी प्राप्त किए गए वर्गों को वर्चुअल फ़ंक्शन के मूल कार्यान्वयन की आवश्यकता होती है, वर्चुअल फ़ंक्शन को सुरक्षित रखें ", आपका प्रश्न शुद्ध वर्चुअल फ़ंक्शन के बारे में है, मुझे पूरा यकीन नहीं है कि इस सिद्धांत को पूरा करें या नहीं।

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