2015-10-21 14 views

उत्तर

13

दो कार्य वास्तव में समान नहीं हैं। केवल दूसरा फ़ंक्शन const सदस्य फ़ंक्शन के रूप में घोषित किया गया है। यदि ऑब्जेक्ट जिसे सदस्य से बुलाया जाता है const है, तो बाद का विकल्प उपयोग किया जाता है। यदि ऑब्जेक्ट गैर- const है, तो पहला विकल्प उपयोग किया जाता है।

उदाहरण:

void any_func(const Type *t) 
{ 
    something = t->value(); //second `const` version used 
} 

void any_func2(Type *t) 
{ 
    something = t->value(); //first non-`const` version used 
} 

यदि दोनों कार्यों गैर const घोषित कर दिया गया या दोनों const घोषित किया गया, संकलक होगा (, वैसे भी चाहिए) शिकायत करते हैं।

7

संकलक क्यों शिकायत नहीं करता है के बारे में

क्योंकि एक अलग समारोह हस्ताक्षर के लिए const गिना जाता है। आपकी धारणा फ़ंक्शन हस्ताक्षर समान गलत है।
const के रूप में चिह्नित फ़ंक्शन को const उदाहरण या Type<T> के संदर्भ के लिए बुलाया जाएगा।

और कैसे पता चलेगा कि किसको आह्वान किया जाता है?

कार्यों में एक cout बयान रखो और निम्नलिखित मामलों का परीक्षण:

template <class T> 
class Type { 
    public: 
     Type() {} 
     T& operator=(const T& rhs) {value() = rhs; return value();} 
     T& value() { 
      std::cout << "non const version" << std endl; 
      return m_value; 
     } 
     T value() const { 
      std::cout << "const version" << std endl; 
      return m_value; 
     } 
    private: 
     T m_value; 
}; 

int main() { 
    Type<int> t; 
    t.value(); 

    Type<int> rt = t; 
    rt.value(); 

    Type<int>* pt = &t; 
    pt->value(); 

    const Type<int> ct; 
    ct.value(); 

    const Type<int>& crt = t; 
    crt.value(); 

    const Type<int>* pct = &t; 
    pct->value(); 
} 

आपका असाइनमेंट ऑपरेटर गैर स्थिरांक संस्करण कॉल करेंगे।


स्थिरांक संस्करण बेहतर तरह

const T& value() const { 
    std::cout << "const version" << std endl; 
    return m_value; 
} 

दिखना चाहिए क्योंकि आप हमेशा RVO (वापसी मान अनुकूलन) पर भरोसा नहीं कर सकते हैं, और अतिरिक्त प्रतियां लिया जा सकता है (विशेष रूप से बड़े संकलक कार्यान्वयन के लिए)।


यह भी ध्यान रखें असाइनमेंट ऑपरेटर वर्तमान उदाहरण के लिए एक संदर्भ लौटना चाहिए:

Type& operator=(const T& rhs) {value() = rhs; return *this;} 
5

कार्यों संकल्प प्राथमिकता के आधार पर शब्दों की एक जोड़ी। कंपाइलर निम्नलिखित तरीके से कॉन्स/गैर कॉन्स फ़ंक्शंस के बीच अंतर करता है:

यदि किसी वर्ग में दिए गए नाम और तर्क सूची के साथ केवल कॉन्स्ट फ़ंक्शन है, तो इसे निरंतर और गैर-निरंतर वस्तुओं के समान कहा जाएगा।इस फ़ंक्शन को कॉल करने के बाद, ऑब्जेक्ट 'दृढ़ता' मान लेगा (भले ही यह स्थिर न हो), जिसका अर्थ है कि फ़ंक्शन केवल अन्य कॉन्स्ट फ़ंक्शंस को कॉल कर सकता है।

यदि किसी वर्ग में केवल गैर-कॉन्स्ट फ़ंक्शन है, तो इसे गैर-कॉन्स्ट ऑब्जेक्ट्स के लिए बुलाया जाएगा। कॉन्स्ट ऑब्जेक्ट्स के लिए इस फ़ंक्शन को कॉल करने का प्रयास संकलन त्रुटि का कारण बन जाएगा।

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

विवरण में प्रारंभिक मिश्रण पर मेरा ध्यान इंगित करने के लिए @owacoder के लिए धन्यवाद।

+3

मुझे लगता है कि दूसरे अनुच्छेद में तर्क पीछे की तरफ है। गैर-'const' फ़ंक्शंस ** ** को 'const' ऑब्जेक्ट्स के लिए नहीं कहा जा सकता है। – owacoder

+0

@owacoder, निश्चित रूप से वे कर सकते हैं। अपने आप को कोशिश करो – SergeyA

+0

@owacoder, मेरा बुरा। आप सही हैं, मैंने आपकी टिप्पणी को गलत तरीके से पढ़ा और मेरा जवाब गलत टाइप किया। इसे संपादित करेंगे। – SergeyA

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