2010-09-30 9 views

उत्तर

0

स्कॉट Meyers, Effective C++, आइटम 3:

उपयोग const जब भी संभव हो

इस विषय पर एक उत्कृष्ट चर्चा (उदाहरण के साथ) है। स्कॉट से बेहतर लिखना मुश्किल है!

ध्यान दें कि भौतिक-स्थिरता को bitwise-constness के रूप में भी जाना जाता है।

17

आप mutable जरूरत है जब वहाँ एक वस्तु में फ़ील्ड "आंतरिक" माना जा सकता है, यानि कि वर्ग के किसी भी बाहरी उपयोगकर्ता इन क्षेत्रों का मूल्य निर्धारित नहीं कर सकते हैं। कक्षा को इन क्षेत्रों में लिखने की आवश्यकता हो सकती है भले ही इंस्टेंस निरंतर माना जाता है, यानी नहीं बदल रहा है।

हार्ड ड्राइव पर विचार करें; इसका कैश ऐसे राज्य का एक उदाहरण है। कैश लिखा जब डेटा वास्तविक डिस्क से पढ़ा गया है।

संबंधित सदस्यों को mutable के बिना सी ++ में स्पष्ट रूप से व्यक्त करना संभव नहीं है, ताकि उन्हें const चिह्नित विधियों में भी बदला जा सके। जैसा कि एक टिप्पणी में बताया गया है, आप हमेशा हथौड़ा तक पहुंच सकते हैं और const -ness को हटाने के लिए const_cast<> का उपयोग कर सकते हैं, लेकिन यह निश्चित रूप से धोखाधड़ी है। :)

+3

एक और ऐसा उदाहरण विभिन्न धागे द्वारा साझा की गई वस्तु में एक म्यूटेक्स होगा। एक पठन ऑपरेशन ऑब्जेक्ट को संशोधित नहीं करता है, लेकिन म्यूटेक्स को अधिग्रहण और प्रक्रिया में जारी किया जाना चाहिए। म्यूटेक्स सदस्य ऑब्जेक्ट ऑपरेशन के दौरान स्पष्ट रूप से बदलता है, भले ही ऑपरेशन का नतीजा ऑब्जेक्ट प्रति-से नहीं बदलता है। यदि कोई तत्व आंतरिक तत्व बदलता है, भले ही माना गया अवस्था अव्यवस्थित रहती है, तो एक ऑब्जेक्ट पर एक ऑपरेशन होता है। –

+0

क्या आप कृपया मुझे छोटा उदाहरण दे सकते हैं (कोड) जो दिखाता है कि मैं म्यूटेबल के साथ क्या कर सकता हूं और कॉन्स्ट के साथ नहीं कर सकता, जो तर्क और शारीरिक स्थिरता के बीच अंतर भी दिखाता है मुझे Google में कुछ स्पष्टीकरण मिले लेकिन अच्छे नहीं मिल सकते उदाहरण के लिए, – rookie

+0

को समझने में थोड़ा मुश्किल कैश के साथ _T संबंधित सदस्यों 'mutable'_ बनाने के बिना C++ में व्यक्त करना संभव नहीं है। यह कथन गलत है, इस पर ** ऑब्जेक्ट या सदस्य कास्टिंग करके दृढ़ता को हटाकर ** ** पूरा किया जा सकता है (और अतीत में)। कीवर्ड 'mutable' के बाद आया था, जब तार्किक स्थिरता का विचार एहसास हुआ था क्योंकि प्रोग्रामर इस प्रभाव को प्राप्त करने के लिए मैन्युअल रूप से ऑब्जेक्ट्स की स्थिरता को हटा रहे थे, जिससे इसे अधिक रखरखाव और लागू करने योग्य बना दिया गया। [यहां] देखें (http://www.linuxtopia.org/online_books/programming_books/thinking_in_c++/Chapter08_025.html)। – Adrian

31

"भौतिक" स्थिरता किसी ऑब्जेक्ट को const घोषित करने से आता है, और सिद्धांत रूप में, ऑब्जेक्ट को केवल-पढ़ने वाली मेमोरी में रखकर लागू किया जा सकता है, इसलिए यह नहीं बदला जा सकता है। इसे बदलने का प्रयास अपरिभाषित व्यवहार का कारण बन जाएगा; यह बदल सकता है, या ऐसा नहीं हो सकता है, या यह सुरक्षा गलती को ट्रिगर कर सकता है, या यह मेमोरी चिप पिघल सकता है।

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

एक mutable वर्ग के सदस्य संशोधित किया जा सकता है, भले ही वर्ग वस्तु ही (या संदर्भ या सूचक इसे उपयोग करने में प्रयोग किया जाता) const है। इसके अच्छे उपयोग के उदाहरण एक म्यूटेक्स हैं जिन्हें पढ़ने के दौरान लॉक किया जाना चाहिए, और एक कैश एक महंगे पठन ऑपरेशन के परिणाम को स्टोर करने के लिए। दोनों मामलों में, ऑपरेशन स्वयं const फ़ंक्शन होना चाहिए (क्योंकि यह ऑब्जेक्ट की दृश्य स्थिति को प्रभावित नहीं करता है), लेकिन इसे म्यूटेक्स या कैश को संशोधित करने की आवश्यकता है, इसलिए इन्हें mutable होना चाहिए। जब तर्कसंगत रूप से यह नहीं होना चाहिए, तो ऑब्जेक्ट को स्पष्ट रूप से बदलने के लिए इसका दुरुपयोग किया जा सकता है, इसलिए इसे देखभाल के साथ उपयोग करें; केवल सदस्यों को mutable घोषित करें यदि वे बाहरी रूप से दिखाई देने वाले राज्य का हिस्सा नहीं बनते हैं।

+1

+1, बहुत अच्छी व्याख्या। – Dan

+1

जो बहुत अच्छी तरह से पढ़ता है :-), लेकिन बहुत गलत है :-(। "भौतिक" स्थिरता ऑब्जेक्ट कॉन्स घोषित करने से आता है "-' const' आपकी "भौतिक स्थिरता" की गारंटी नहीं देगा: सदस्य अभी भी 'उत्परिवर्तनीय' हो सकते हैं और रन-टाइम में बदल दिया गया। क्योंकि इसकी अनुमति है, कंपाइलर/लिंकर इत्यादि ऐसी वस्तुओं को डिफ़ॉल्ट रूप से रीड-ओनली मेमोरी में नहीं रखेगा, भले ही वे 'स्थिर कॉन्स' हों। अगर उन्हें कुछ गैर- - मानक कंपाइलर/लिंकर/लोडर झंडे, तो प्रोग्रामर को मैन्युअल रूप से 'म्यूटेबल' सदस्यों से बचना चाहिए। ऑब्जेक्ट्स और पॉइंटर/संदर्भों के बीच जो अंतर आप आकर्षित करते हैं वह वास्तव में अप्रासंगिक है। –

+0

@ टोनीडेलॉय - मैंने माइक की प्रतिक्रिया ली जिसमें "ऑब्जेक्ट को पढ़ने- केवल स्मृति "भौतिक और तार्किक 'const'-ness के बीच अंतर के बारे में एक बिंदु बनाने के लिए एक उदारवादी (और उदारतापूर्वक प्रभावी) कथन के रूप में, एक बयान के रूप में नहीं कि संकलक वास्तव में ऐसा करेंगे, और न ही उन्होंने कहा कि कंपाइलर्स * करेंगे * यह भी। मैं असहमत हूं कि उसकी disti पॉइंटर्स और संदर्भों के बीच nction अप्रासंगिक है। जवाब अवधारणात्मक रूप से ठोस और सही है। टोनीडेलॉय, मेरी राय में, सही नहीं है जब वह कहता है कि जवाब "बहुत गलत" है। –

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