2012-12-26 15 views
10

मैंने दो वर्गों, एक कॉन्स और एक गैर-कॉन्स के साथ एक कक्षा बनाई है। कॉन्स विधि सार्वजनिक है, इसलिए उपयोगकर्ता वेक्टर से पूछ सकते हैं। गैर-कॉन्स्ट विधि सुरक्षित है, इसलिए मैं इसे आवश्यक डेटा को संशोधित करने के लिए इसका उपयोग कर सकता हूं।जब कोई कॉन्स्ट विधि सार्वजनिक होती है और गैर-कॉन्स्टेंस संरक्षित होता है तो सी ++ क्यों नहीं खड़ा होता है?

जब मैं कक्षा का उपयोग करने की कोशिश करता हूं, और प्राप्त विधि को कॉल करता हूं, तो संकलक शिकायत करता है कि गैर-कॉन्स्ट विधि सुरक्षित है। इसके बजाय, मुझे ऑब्जेक्ट को कॉस्ट करने के लिए const_cast का उपयोग करना होगा, इसलिए मैं इसके बजाय सार्वजनिक विधि प्राप्त कर सकता हूं।

क्या इसे हल करने का कोई तरीका है? एक सार्वजनिक विधि क्यों है, इसलिए संकलक स्वयं कास्ट क्यों नहीं करेगा? अगर मैं संरक्षित संस्करण को हटा देता हूं और केवल एक को छोड़ देता हूं, तो यह ठीक काम करता है, इसलिए यह इस स्थिति में कलाकार करता है। कॉन्स को कास्टिंग हमेशा सुरक्षित है। यह एक समस्या है जो स्थिरता को हटा रहा है।

उत्तर

3

संकलक के बाद पहुंच मानता है यह तय करता है कि वह किस सदस्य फ़ंक्शन को कॉल करना चाहता है। यही है, संरक्षित और निजी कार्य अभी भी दृश्यमान हैं, भले ही वे उपलब्ध नहीं हैं

क्यों? एक कारण यह है कि यदि आपने ओवरलोड रिज़ॉल्यूशन द्वारा अनचाहे कार्यों को अनदेखा कर दिया है, तो आप इसकी पहुंच को बदलकर बस किस फ़ंक्शन को कॉल कर सकते हैं बदल सकते हैं। वर्तमान नियमों के साथ, आप केवल संकलन कोड को संकलित करने में विफल होने का कारण बन सकते हैं, या कोड का कारण बन सकते हैं जो वर्तमान में संकलित करने के लिए काम नहीं करता है, या कोड के अर्थ पर कोई प्रभाव नहीं पड़ता है। आप एक्सेस विनिर्देशों को नहीं बदल सकते हैं और चुपचाप एक अलग फ़ंक्शन कहलाते हैं।

public: 
    // Returns the amount of change tendered for this transaction. 
    MoneyAmount change() const; 

private: 
    // Account for a change of currency. Charges standard moneychanger's fee. 
    MoneyAmount change(Currency toCurrency = Currency::USD); 

तो दुर्गम कार्यों अधिभार संकल्प से हटा दिया गया, ग्राहक कोड change() ठीक कह सकते हैं:

एक काल्पनिक उदाहरण के रूप में, यहाँ एक बहुत भयानक वर्ग इंटरफेस है। और यदि बाद में दूसरा change(Currency) फ़ंक्शन सार्वजनिक किया गया था और पहला व्यक्ति हटा दिया गया था, तो वह कोड अचानक चुपचाप एक और फ़ंक्शन को पूरी तरह से अलग उद्देश्य से कॉल करेगा। वर्तमान नियम एक संकलन कार्यक्रम के व्यवहार को बदलने से एक्सेस विनिर्देशक के परिवर्तन को रोकते हैं।

0

सी ++ में, विधि चयन (ओवरलोडिंग रिज़ॉल्यूशन) सार्वजनिक/निजी पहुंच नियंत्रण पर विचार करने से पहले होता है।

0

नॉन कॉन्स्ट गेटर विधि के बजाय एक संरक्षित सेटर विधि (या डेटा सदस्य) का उपयोग करें।

यदि आपके पास है तो इससे कोई फर्क नहीं पड़ता। जैसे

class A { 
    SomeType foo_; 
protected: 
    SomeType& foo() { return foo_; } 

public: 
    const SomeType& foo() const { return foo_; } 
}; 

या

class A { 
protected: 
    SomeType foo_; 

public: 
    const SomeType& foo() const { return foo_; } 
}; 
6

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

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

समाधान केवल आपके संरक्षित सदस्य फ़ंक्शन का नाम बदलना है ताकि इसे नहीं माना जा सके।

0

यह सी ++ का प्रकृति व्यवहार है, यदि कॉलर कोड कक्षा का ऑब्जेक्ट गैर-कॉन्स्ट है तो गैर-रूपांतरण, जिसे संरक्षित के रूप में परिभाषित किया गया है। आपको कक्षा के ऑब्जेक्ट पर कक्षा के ऑब्जेक्ट को कॉन्स्ट के रूप में परिभाषित करने या कॉन्स्ट-कास्ट का उपयोग करने की आवश्यकता है, जिसके परिणामस्वरूप विधि का कॉन्स्ट संस्करण कहा जाएगा।

#include <iostream> 
class Foo { 
    public: 
     const void bar() const { std::cout << " const version called\n";} 
    protected: 
     void bar() { std::cout << " non const version called\n";} 
}; 

int main(int argc, char** argv) 
{ 
    const Foo c; 
    c.bar(); // -> work 

    Foo c1; 
    c1.bar(); // compiler complain -> void Foo::bar() is protected 
    const_cast<const Foo&>(c1).bar(); // fine 
} 
संबंधित मुद्दे

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