2016-11-16 11 views
6
#include <iostream> 

struct A 
{ 
    virtual void foo(){ std::cout << "A"; }; 
}; 

struct B : public A 
{ 
private: 
    void foo() override { std::cout << "B"; } 
}; 

int main() 
{ 
    A *p = new B; 
    p->foo();  // prints B 

// B b; 
// b.foo();  // error: foo is private 
    return 0; 
} 

// g++ -std=c++11 -Wall -Wextra -Wpedantic main.cpp && ./a.out 

तो हम B.foo() पॉलिमॉर्फिक रूप से कॉल कर सकते हैं, लेकिन सीधे नहीं। क्या कोई उपयोग केस है, जब कोई इस कार्यक्षमता का उपयोग करना चाहेगा?क्या निजी सार्वजनिक-वर्चुअल विधियों के लिए केस का उपयोग किया जाता है?

उत्तर

2

यह आपको गैर-बहुरूप रूप से विधि को कॉल करने से रोकता है, यह सब कुछ है: स्कोप रिज़ॉल्यूशन ऑपरेटर का उपयोग करके किसी विधि को सीधे एक्सेस करने के लिए कोड को बनाए रखना मुश्किल हो सकता है। ऐसे माहौल में जहां आप जानते हैं कि हर कोई एक अनुभवी कार्यान्वयनकर्ता नहीं है (वैज्ञानिक प्रोग्रामर शायद बड़े कोडबेस में योगदान दे रहे हैं), यह आपके कोड को सुरक्षित रखने के लिए पैटर्न पेश करने योग्य है!

उस ने कहा, जावा स्पष्ट रूप से इसे खराब करता है क्योंकि वे इसे खराब शैली मानते हैं।

+1

फिर फिर, जावा क्या प्रतिबंधित नहीं करता है। –

5

यह प्रकार बेस क्लास के डिजाइन पर निर्भर करता है। मान लीजिए आप एक आधार वर्ग है

class Stream { 
public: 
    virtual bool canSeek() = 0; 
    virtual void seek(int offset) = 0; 
}; 

नोट: इस उदाहरण नेट दुनिया है, जहां आधार वर्ग पुस्तकालय Stream वर्ग वास्तव में इस तरह के एक आभासी CanSeek संपत्ति है से आता है। मैं चर्चा नहीं करना चाहता कि यह अच्छा डिजाइन है, क्योंकि मैं दोनों पक्षों के लिए वैध तर्क देख सकता हूं। यह पर्याप्त है कि इस तरह के आधार वर्ग वास्तविकता में मौजूद हैं।

अब, एक व्युत्पन्न वर्ग को निर्दिष्ट कर सकता है कि

class SpecificStream final : Stream { 
private: 
    virtual bool canSeek() { return false; } 
    virtual void seek(int offset) { throw "no seek for you"; } 
} 

इस व्युत्पन्न वर्ग में, तथ्य यह है कि seek सब पर लागू किया गया है है, क्योंकि यह तकनीकी रूप से आवश्यक है। हालांकि, इस SpecificStream से संबंधित किसी भी कोड को पहले से ही पता है कि seek फ़ंक्शन इस कक्षा के साथ पूरी तरह बेकार है और इसे नहीं बुलाया जाना चाहिए। Stream कक्षा के आधार पर कोडिंग करते समय, canSeek() के परिणाम की जांच करने के लिए यह समझ हो सकता है और परिणाम केवल seek पर कॉल कर सकता है यदि परिणाम सत्य था। SpecificStream कक्षा के विरुद्ध कोडिंग करते समय, canSeek() की जांच करने के लिए यह समझ में नहीं आता है, क्योंकि इसका परिणाम सांख्यिकीय रूप से ज्ञात है, और यह निश्चित रूप से seek() पर कॉल करने के लिए समझ में नहीं आता है। यदि ऐसी कॉल प्रोग्रामर त्रुटि होगी, तो कंपेलर ऐसी कॉल के लिए उपयोगी संदेश देने में मदद करने के लिए समझ में आता है।

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