[C++] सी ++: क्यों बुराई const_cast है?


Answers

कॉन्स्ट का उपयोग करके, मैं अपने संदर्भ को परिवर्तित होने से बचा रहा हूँ

सन्दर्भ परिवर्तित नहीं किए जा सकते हैं, एक बार प्रारंभ होने पर वे हमेशा एक ही वस्तु का संदर्भ देते हैं। एक संदर्भ const मतलब वस्तु का अर्थ है जिसे बदला नहीं जा सकता। लेकिन const_cast उस तर्क को पूर्ववत नहीं करता है और ऑब्जेक्ट को सभी के बाद परिवर्तित करने की अनुमति देता है।

दूसरी ओर, अगर मैं const_cast का उपयोग नहीं करता, तो कोड संकलन नहीं करेगा।

यह कुछ के लिए एक औचित्य नहीं है सी ++ कोड संकलित करने से इंकार करता है जो const ऑब्जेक्ट को परिवर्तित करने की अनुमति दे सकता है क्योंकि यह const का अर्थ है ऐसा कार्यक्रम गलत होगा। const_cast गलत प्रोग्रामों को संकलित करने का एक साधन है - यही समस्या है।

उदाहरण के लिए, आपके प्रोग्राम में, ऐसा लगता है कि आपके पास ऑब्जेक्ट है

std::vector< SysOscillatorBase<T> * > oscillators

इस पर विचार करो:

Oscillator o; // Create this object and obtain ownership
addOscillator( o ); // cannot modify o because argument is const
// ... other code ...
oscillators.back()->setFrequency( 3000 ); // woops, changed someone else's osc.

Const संदर्भ द्वारा किसी ऑब्जेक्ट को पास करना न केवल इसका मतलब है कि फ़ंक्शन फ़ंक्शन इसे बदल नहीं सकता है, लेकिन यह फ़ंक्शन किसी अन्य व्यक्ति को बदल सकता है जो इसे बदल सकता है। const_cast उल्लंघन करता है कि

सी + + की ताकत यह है कि यह स्वामित्व और मूल्य शब्दों के बारे में चीजों की गारंटी करने के लिए उपकरण प्रदान करता है। जब आप प्रोग्राम को संकलित करने के लिए उन टूल को अक्षम करते हैं, तो यह बग को सक्षम करता है कोई अच्छा प्रोग्रामर यह स्वीकार करता है कि स्वीकार्य नहीं है

इस विशेष समस्या का एक समाधान के रूप में, ऐसा लगता है कि vector (या जो भी कंटेनर आप उपयोग कर रहे हैं) ऑब्जेक्ट को मूल्य से संचित करना चाहिए, सूचक नहीं। तब addOscillator एक const संदर्भ स्वीकार कर सकते हैं और फिर भी संग्रहीत ऑब्जेक्ट्स addOscillator हैं। इसके अलावा, कंटेनर फिर ऑब्जेक्ट्स का मालिक है और यह सुनिश्चित करता है कि वे सुरक्षित रूप से हटाए गए हैं, आपकी ओर से कोई काम नहीं है।

Question

मैं इस कथन को सुनता रहता हूं, जबकि मुझे वास्तव में पता नहीं चल पाया कि const_cast बुरा है

निम्नलिखित उदाहरण में:

template <typename T>
void OscillatorToFieldTransformer<T>::setOscillator(const SysOscillatorBase<T> &src)
{
    oscillatorSrc = const_cast<SysOscillatorBase<T>*>(&src);
}

मैं एक संदर्भ का उपयोग कर रहा हूं, और कॉन्स्ट का इस्तेमाल करके, मैं अपने संदर्भ को परिवर्तित होने से बचा रहा हूँ दूसरी ओर, अगर मैं const_cast का उपयोग नहीं करता, तो कोड संकलन नहीं करेगा। क्यों बुरा होगा const_cast यहाँ बुरा होगा?

वही निम्न उदाहरण पर लागू होता है:

template <typename T>
void SysSystemBase<T>::addOscillator(const SysOscillatorBase<T> &src)
{
    bool alreadyThere = 0;
    for(unsigned long i = 0; i < oscillators.size(); i++)
    {
        if(&src == oscillators[i])
        {
            alreadyThere = 1;
            break;
        }
    }
    if(!alreadyThere)
    {
        oscillators.push_back(const_cast<SysOscillatorBase<T>*>(&src));
    }
}

कृपया मुझे कुछ उदाहरण दें, जिसमें मैं देख सकता हूं कि const_cast का उपयोग करने के लिए यह एक बुरा विचार / अव्यवसायिक है।

किसी भी प्रयास के लिए धन्यवाद :)




const_cast खराब होगा क्योंकि यह आपको विधि द्वारा निर्दिष्ट अनुबंध को तोड़ने की अनुमति देता है, यानी "मैं src संशोधित नहीं करेगा" कॉलर को उम्मीद है कि इस पद्धति को छड़ी करना चाहिए।




, जबकि मुझे वाकई कारण नहीं मिल सकता है क्योंकि const_cast बुरा है

ऐसा नहीं है, जब जिम्मेदारी से उपयोग किया जाता है और जब आप जानते हैं कि आप क्या कर रहे हैं (या आप उन सभी तरीकों के लिए गंभीर रूप से कॉपी पेस्ट कोड करते हैं जो केवल उनके कॉन्स्ट मॉडिफायर के कारण भिन्न होते हैं?)

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

आपके उदाहरण में यह स्थिति ठीक है: संभवत: गैर-कॉन्स्ट में परिवर्तित कन्वेंबल चर समस्या से बचने के लिए या तो अपने ऑब्जेक्ट सूची में const SysOscillatorBase<T>* (const पॉइंटर) या SysOscillatorBase<T> (प्रतिलिपि) या संदर्भ संदर्भ के बजाय संदर्भ पास करें।




आप एक कोडन अनुबंध का उल्लंघन कर रहे हैं मान के रूप में मान चिह्नित करना कह रहा है कि आप इस मान का उपयोग कर सकते हैं लेकिन इसे कभी भी बदल नहीं सकते const_cast इस वादे को तोड़ता है और अप्रत्याशित व्यवहार बना सकता है

आपके द्वारा दिए गए उदाहरणों में, ऐसा लगता है कि आपका कोड बिल्कुल सही नहीं है थरथरानवाला एसआरसी संभवतः एक कॉन्स्ट पॉइंटर हो सकता है, यद्यपि यदि आपको वास्तव में मूल्य बदलने की ज़रूरत है तो आपको उसे किसी const के रूप में नहीं देना चाहिए






Links