2012-07-12 27 views
8

मेरी समझ से, mutable रद्द एक चरconst_cast वीएस mutable? कोई अंतर?

Class A { 
    void foo() const { 
    m_a = 5; 
} 
mutable int m_a; 
}; 

की constness लेकिन भी const_cast:

void print (char * str) 
{ 
    cout << str << endl; 
} 

int main() { 
    const char * c = "this is a line"; 
    print (const_cast<char *> (c)); 
    return 0; 
} 

तो, दूसरे से क्या परिवर्तन?

धन्यवाद

उत्तर

16

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

उदाहरण के लिए, इस const_cast

int i = 5; // non-constant object 
    const int *p = &i; // `p` is a const access path to `i` 

    // Since we know that `i` is not a const, we can remove constness... 
    int *q = const_cast<int *>(p); 
    // ... and legally modify `i` 
    *q = 10; 
    // Now `i` is 10 

एकमात्र कारण ऊपर कानूनी और वैध है की अभीष्ट उपयोग दिखाता है तथ्य यह है कि i वास्तव में एक गैर निरंतर वस्तु है, और हम इस बारे में पता है ।

यदि मूल वस्तु वास्तव में निरंतर था, तो इसके बाद के संस्करण कोड अपरिभाषित व्यवहार का उत्पादन होगा:

const int j = 5; // constant object 
    const int *p = &j; // `p` is a const access path to `j` 

    int *q = const_cast<int *>(p); // `q` is a non-const access path to `j` 
    *q = 10; // UNDEFINED BEHAVIOR !!! 

C++ भाषा आप लगातार वस्तुओं को संशोधित करने की अनुमति नहीं है और const_cast यहां पूरी तरह से शक्तिहीन है, तो आप कैसे उपयोग की परवाह किए बिना यह।

mutable एक पूरी तरह से अलग बात है। mutable दायर एक डेटा बनाता है जिसे कानूनी रूप से संशोधित किया जा सकता है भले ही युक्त ऑब्जेक्ट const घोषित किया गया हो। उस अर्थ में mutable आपको निरंतर वस्तुओं के कुछ निर्दिष्ट भागों को संशोधित करने की अनुमति देता है। दूसरी ओर, const_cast, ऐसा कुछ भी नहीं कर सकता है।

1

अंतर अर्थपूर्ण है - i। ई। एक ही जेनरेट कोड, एक ही रन-टाइम परिणाम (const नेस पूरी तरह से संकलित-समय का निर्माण होता है), लेकिन दोनों संरचनाएं थोड़ा अलग अर्थ बताती हैं।

विचार यह है कि आप वर्ग में मौजूद चर के लिए mutable का उपयोग करते हैं, लेकिन ऑब्जेक्ट की स्थिति का गठन नहीं करते हैं। क्लासिक उदाहरण ब्लॉब ऑब्जेक्ट में वर्तमान स्थिति है। ब्लॉब में नेविगेट करना किसी भी तरह से ब्लॉब को "संशोधित" के रूप में नहीं मानता है। mutable का उपयोग करके, आप कह रहे हैं "यह चर बदल सकता है, लेकिन ऑब्जेक्ट अभी भी वही है"। आप यह बता रहे हैं कि इस विशेष वर्ग के लिए, const -ness का मतलब यह नहीं है कि "सभी चर जमे हुए हैं"।

const_cast, दूसरी तरफ, इसका मतलब है कि आप मौजूदा कॉन्स शुद्धता का उल्लंघन कर रहे हैं और इससे दूर जाने की उम्मीद है। शायद क्योंकि आप किसी तृतीय पक्ष एपीआई के साथ काम कर रहे हैं जो const (ई जी। पुराना स्कूल सी-आधारित एक) का सम्मान नहीं करता है।

4

अंतर यह है कि const_cast धोखा नहीं सकता है, लेकिन mutable नियमों का अपवाद है।

पहले स्निपेट m_a पर mutable है, और इस प्रकार नियम के अपवाद है कि आप const सदस्य कार्यों पर डेटा सदस्यों को संशोधित नहीं कर सकते हैं।

दूसरा टुकड़ा पर, const_cast धोखा देने के लिए कोशिश करता है, लेकिन वास्तव में नहीं कर सकते हैं: जबकि प्रकार बदल गया है, वास्तविक संशोधन अनुमति नहीं है: स्ट्रिंग सही मायने में const है। इसे संशोधित करने का प्रयास कार्यक्रम को अपरिभाषित व्यवहार प्रदर्शित करने का कारण बनता है।

0

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

जब तक आप किसी सदस्य चर के लिए लेखन पहुंच को स्पष्ट रूप से अनुमति नहीं देना चाहते हैं, तो const_cast का उपयोग करकेका उपयोग करके स्थिरता के उल्लंघन के हर मामले में प्राथमिकता दी जाती है, अगर केवल आपके इरादे स्पष्ट रूप से बताए जाएं।

एक तरफ नोट पर, volatile संशोधक जोड़ने या निकालने के लिए const_cast का भी उपयोग किया जा सकता है।