2014-09-20 4 views
7

मैं एक्सेस विनिर्देशों को स्थिर या गतिशील रूप से जांचने के बारे में उलझन में हूं। ऐसा कहा जाता है कि एक्सेस विनिर्देशों को गतिशील रूप से चेक नहीं किया जाता है। इसका क्या मतलब है ?कथन को समझने की आवश्यकता है "एक्सेसिबिलिटी को सांख्यिकीय रूप से चेक किया गया है और सी ++ में गतिशील रूप से नहीं है"

यह उदाहरण SO पर विभिन्न posts से लिया गया है। इस उदाहरण पर विचार

उदाहरण A:

class Base 
{ 
public: 
    virtual void Message() = 0; 
}; 

class Intermediate : public Base 
{ 
    //Is Message method virtual here too ? is it private or public ? 
}; 

class Final : public Intermediate { 
    void Message() { 
     cout << "Hello World!" << endl; 
    } 
}; 

Final final; 

अब मैं इस

Final* finalPtr = &final; 
finalPtr->Message(); 

ऊपर अभ्यस्त काम की तरह कुछ करते हैं और मैं समझता हूँ कि अंतिम कक्षा में संदेश विधि निजी है लगता है। क्या वो सही है ? यदि ऐसा है तो यह क्यों काम करता है?

Intermediate* finalPtr = &final; // or Base* finalPtr = &final; 
    finalPtr->Message(); 

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

अद्यतन:

भी मैंने देखा है कि अगर मैं निम्नलिखित

class Intermediate : public Base 
{ 
public: //Incase this public was absent then the following example wont work 
    void Message() { 
     cout << "Hello World! Intermediate" << endl; 
    } 
}; 

class Final : public Intermediate { 
    void Message() { 
     cout << "Hello World! final" << endl; 
    } 
}; 

को Intermediate और Final कोड बदल सकते हैं और यह रूप में इस तरह

Intermediate* i = new Final(); 
    i->Message(); 

तब उपयोग करने के लिए inorder आउटपुट "Hello World! final" प्राप्त करें इंटरफ़ेस को चिह्नित करना आवश्यक है जनता के रूप में विधि। ऐसा क्यों है ? विधि Message को जनता के रूप में विरासत में मिला था। मुझे इसे सार्वजनिक रूप से चिह्नित करने की आवश्यकता क्यों है?

+1

आपको अन्य पोस्ट को लिंक करना चाहिए था। क्योंकि आपने नहीं किया, आपको वही स्पष्टीकरण मिलेगा जिसे आप समझ में नहीं आते हैं। –

+0

ने अभी लिंक – Rajeshwar

उत्तर

8

अपने उद्धरण में बयान का मतलब है कि पहुँच जांच अभिव्यक्ति के स्थिर प्रकार के आधार पर किया जाता है आप के लिए . ऑपरेटर (या -> जो . साथ * के बराबर है) आवेदन किया है।

तो T एक प्रकार के लिए तो यह है:

T *t = something....; 
t->foo(); 

पहुँच जाँच नाम T::foo के लिए है, भले ही सूचक वास्तव में एक वर्ग foo से प्राप्त की एक वस्तु की ओर इशारा करता।

यह कहने का एक और तरीका यह है कि पहुंच जांच संकलन-समय पर निष्पादित करने में सक्षम होना चाहिए। "रन-टाइम एक्सेसिबिलिटी विफलता" जैसी कोई चीज़ नहीं है।


अपने कोड उदाहरण में आपके पास:

Intermediate* finalPtr = something.....; 
finalPtr->Message(); 

नाम ऊपर देखा जा रहा Intermediate::Message है। Intermediate में Messagepublic फ़ंक्शन के रूप में है, इसलिए यह चेक सफल हो जाती है।

आपकी टिप्पणी से पता चलता है कि आप विरासत कार्यों की पहुंच के बारे में अनिश्चित हैं। तीन प्रकार के व्युत्पन्न होते हैं (कुछ हद तक भ्रमित, उन्हें private, protected, public भी कहा जाता है)। public विरासत सबसे आम है; इसका मतलब है कि public बेस क्लास के सदस्य भी public व्युत्पन्न वर्ग के सदस्य हैं।

Base::Message के बाद से सार्वजनिक है और यह Intermediate सार्वजनिक रूप से Base से प्राप्त होता है, तो Intermediate::Message भी सार्वजनिक है।

स्पष्ट होने के लिए, यह नाम है जिसका उपयोग अधिकार है। Base::Message और Intermediate::Message दो अलग-अलग नाम हैं, लेकिन वे दोनों एक ही कार्य का नाम देते हैं।

Final में, यह private अनुभाग में Message नाम घोषित करता है, इसका मतलब है कि Final::Message निजी है। भले ही विरासत सार्वजनिक थी, नाम Final::Message नाम की नई घोषणा बेस से विरासत में मिली है।


"अद्यतन" का उत्तर देने के लिए। जब कोड है:

class Intermediate : public Base 
{ 
public: //Incase this public was absent then the following example wont work 
    void Message() { 
     cout << "Hello World! Intermediate" << endl; 
    } 
}; 

आप Intermediate::Message सार्वजनिक रूप में घोषित किया है। इसलिए आप Intermediate * प्रकार के सूचक के माध्यम से फ़ंक्शन को कॉल कर सकते हैं। यही "सार्वजनिक" मतलब है। यदि आप इसे private बनाते हैं तो आप इसे कॉल नहीं कर सकते हैं।

मुझे पता नहीं है कि "विधि संदेश को जनता के रूप में विरासत में मिला था। मुझे इसे सार्वजनिक रूप से चिह्नित करने की आवश्यकता क्यों है"। जब आपने class Intermediate के अंदर लिखा था तो यह एक नया कार्य घोषित करता है। उस फ़ंक्शन का नाम विरासत में नाम छाया करता है।

+0

फिर यह कहना सही होगा कि यदि बेस क्लास को व्युत्पन्न कक्षा के साथ तुरंत चालू किया जाता है। फिर बेस क्लास विधि के एक्सेस विनिर्देशित व्युत्पन्न वर्ग के एक्सेस विनिर्देशक पर प्राथमिकता लेती है? – Rajeshwar

+0

ऐसी कोई चीज नहीं है जैसे "आधार वर्ग को व्युत्पन्न वर्ग के साथ तत्काल किया जाता है", ताकि यह सही न हो। –

+0

@ राजेश्वर ने –

4

यह जांच केवल संकलन समय पर की जाती है।

आपने संदेश() को अंतिम रूप में सार्वजनिक किया है ताकि इसे अंतिम से बुलाया जा सके।

इंटरमीडिएट क्लास को कोई जानकारी नहीं है कि अंतिम श्रेणी में संदेश कैसे परिभाषित किया गया है।

+0

जोड़ा है तो यह सही होगा? यदि एक बेस क्लास एक व्युत्पन्न वर्ग के साथ तत्काल है। फिर बेस क्लास विधि के एक्सेस विनिर्देशित व्युत्पन्न वर्ग के एक्सेस विनिर्देशक पर प्राथमिकता लेती है? – Rajeshwar

+0

@ राजेश्वर यदि आपके पास बेस क्लास के लिए पॉइंटर है, तो आप केवल बेस क्लास इंटरफ़ेस का उपयोग कर सकते हैं, कंपाइलर को यह पता नहीं है कि वह पॉइंटर वास्तव में क्या इंगित करता है। – molbdnilo

+0

क्या?उन्होंने क्लास फाइनल में संदेश() निजी बनाया, इसलिए इसे अंतिम संदर्भ के लिए संदर्भ/सूचक के माध्यम से नहीं कहा जा सकता है। हालांकि यह संकलन समय पर (स्थिर रूप से) चेक किया गया है, इसलिए यदि रनटाइम पर ऑब्जेक्ट का गतिशील प्रकार अंतिम है, तो फ़ंक्शन सुलभ रहता है। –

1

मैट मैकनब का जवाब छोटा करने के लिए। यदि आप फ़ंक्शन की पहुंच निर्दिष्ट नहीं करते हैं तो यह निजी है। अंतिम की तरह :: संदेश

अभिभावक वर्ग की पहुंच को कम करने के लिए व्युत्पन्न वर्ग के लिए संभव है। यह कुछ मामलों में उपयोगी है (जैसे डिफ़ॉल्ट/प्रतिलिपि बनाने वाले, आदि को अवरुद्ध करना)

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