फ़ंक्शन नाम c ++ के बाद पैरामीटर बनाम const से पहले const


86

क्या अंतर है कुछ इस तरह से विश्वासघात

friend Circle copy(const Circle &);

और ऐसा ही कुछ

friend Circle copy(Circle&) const;

मुझे पता है कि फंक्शन का उपयोग संकलक को यह बताने के लिए किया जाता है कि यह फ़ंक्शन उस ऑब्जेक्ट को बदलने का प्रयास नहीं करेगा जिस पर उसे बुलाया गया है, दूसरे के बारे में क्या है?


6
आप पैरामीटर नहीं बदलेंगे अन्य
चाड

जवाबों:


194

पहले रूप का मतलब है कि Circleसंदर्भ के लिए बाध्य वस्तु की स्थिति ( जो कि copy()फ़ंक्शन का पैरामीटर है, copy()उस संदर्भ के माध्यम से बदल नहीं जाएगी । संदर्भ एक संदर्भ है const, इसलिए Circleउस संदर्भ के सदस्य कार्यों को लागू करना संभव नहीं होगा जो स्वयं के रूप में योग्य नहीं हैं const

दूसरी ओर, दूसरा रूप, गैरकानूनी है: केवल सदस्य कार्यों को ही constअयोग्य ठहराया जा सकता है (जबकि आप जो घोषणा कर रहे हैं वह एक वैश्विक, friendकार्य है)।

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

इसे कोड के साथ कहने के लिए:

struct X
{
    void foo() const // <== The implicit "this" pointer is const-qualified!
    {
        _x = 42; // ERROR! The "this" pointer is implicitly const
        _y = 42; // OK (_y is mutable)
    }

    void bar(X& obj) const // <== The implicit "this" pointer is const-qualified!
    {
        obj._x = 42; // OK! obj is a reference to non-const
        _x = 42; // ERROR! The "this" pointer is implicitly const
    }

    void bar(X const& obj) // <== The implicit "this" pointer is NOT const-qualified!
    {
        obj._x = 42; // ERROR! obj is a reference to const
        obj._y = 42; // OK! obj is a reference to const, but _y is mutable
        _x = 42; // OK! The "this" pointer is implicitly non-const
    }

    int _x;
    mutable int _y;
};

11
नरकवा उत्तर! धन्यवाद!
सेक्सीबस्ट

1
तो, दूसरे मामले के लिए, अगर मेरे पास कक्षा की एक constवस्तु objहै X, और मुझे कॉल करना bar()पसंद है obj.bar(obj), तो क्या होने वाला है और क्यों? obj._x = 42विफल नहीं होना चाहिए , क्योंकि कॉलर में objघोषित constकिया गया है?
सेक्सीबाईट

1
उस मामले के बारे में क्या है जहां आप बाद वाले बार फ़ंक्शन ( void bar(X const& obj) {...}) को इस तरह देखते हैं? void bar(const X& obj) {...}, क्या constइस स्थान पर कीवर्ड ले जाने से कुछ भी बदल जाता है? यदि हां, तो क्या आप इस उदाहरण को भी जोड़ सकते हैं?
गेब्रियल स्टेपल्स

1
@ गैब्रिएलस्टैपल्स वे समान हैं; constलागू होता है जो इसके बाईं ओर होता है, या इसके दाईं ओर क्या होता है यदि बाईं ओर कुछ भी नहीं है। आपके मामले में आप देखेंगे कि दोनों संस्करणों के constलिए लागू किया गया है X
एंड्रियास फ्लॉज्ट

69

C ++ वर्ग विधियों में एक अंतर्निहित thisपैरामीटर है जो सभी स्पष्ट लोगों के सामने आता है। तो इस तरह एक वर्ग के भीतर घोषित एक समारोह:

class C {
  void f(int x);

आप कल्पना कर सकते हैं कि वास्तव में ऐसा दिखता है:

  void f(C* this, int x);

अब, यदि आप इसे इस तरह घोषित करते हैं:

  void f(int x) const;

यह ऐसा है जैसे आपने यह लिखा है:

  void f(const C* this, int x);

यही है, अनुगामी पैरामीटर को कॉन्स्टेबल constबनाता है this, जिसका अर्थ है कि आप क्लास प्रकार की कॉस्ट ऑब्जेक्ट पर विधि को लागू कर सकते हैं, और यह विधि उस ऑब्जेक्ट को संशोधित नहीं कर सकती है जिस पर इसे लागू किया गया था (कम से कम, सामान्य चैनलों के माध्यम से नहीं)।


2
हालाँकि यह पूरी तरह से सही है लेकिन यह सवाल का जवाब नहीं देता है, जो वास्तव में एक क्लास पद्धति का नहीं बल्कि एक फ्रेंड फंक्शन का है।
महिंद्रा

5
हाँ, मैंने इस friendभाग को नजरअंदाज करने का विकल्प चुना क्योंकि मुझे लगता है कि यह वास्तव में ओपी के वास्तविक प्रश्न के लिए अप्रासंगिक है (या सभी मुद्दों के प्रकाश में आने पर वास्तविक प्रश्न बन जाएगा)। ऐसा ही होगा।
जॉन Zwinck

मुझे लगता है कि यह कहना थोड़ा भ्रामक है कि "आप वर्ग प्रकार की कास्ट ऑब्जेक्ट्स पर विधि का उपयोग कर सकते हैं" क्योंकि आप कॉस्ट ऑब्जेक्ट्स या नॉन कॉस्ट ऑब्जेक्ट्स पर कॉन्स्टॉक विधि को लागू कर सकते हैं, जबकि गैर-कॉस्ट फ़ंक्शन को केवल गैर-कॉस्ट ऑब्जेक्ट्स द्वारा बुलाया जा सकता है। अन्यथा यह मेरा पसंदीदा उत्तर है
csguy

8
Circle copy(Circle&) const;

कार्य constकरता है। यह केवल एक वर्ग / संरचना के सदस्य कार्यों के लिए उपयोग किया जा सकता है।

एक सदस्य समारोह बनाने का constमतलब है कि

  • यह किसी भी गैर-कास्ट सदस्य कार्य को कॉल नहीं कर सकता है
  • यह किसी भी सदस्य चर को नहीं बदल सकता है
  • इसे एक constऑब्जेक्ट द्वारा बुलाया जा सकता है ( constऑब्जेक्ट केवल constफ़ंक्शन को कॉल कर सकते हैं )। नॉन-कास्ट ऑब्जेक्ट भी एक constफ़ंक्शन कह सकते हैं ।
  • यह कक्षा ' सर्कल ' का सदस्य कार्य होना चाहिए ।

अब अगले एक पर विचार करें:

Circle copy(const Circle &);

जबकि इसका मतलब यह है कि पारित पैरामीटर को फ़ंक्शन के भीतर नहीं बदला जा सकता है। यह कक्षा का सदस्य कार्य हो भी सकता है और नहीं भी।

ध्यान दें: इस तरह से एक फ़ंक्शन को अधिभार देना संभव है constऔर एक ही फ़ंक्शन का गैर-कॉन्स्टेबल संस्करण है।


7

सभी के संबंध में स्पष्ट है const


constनिरंतर मतलब से आया कुछ परिवर्तनशील नहीं है लेकिन पठनीय है।

  1. यदि हम अपने वैरिएबल को constकीवर्ड के साथ योग्य करते हैं , तो हम इसे बाद में नहीं बदल सकते
    उदाहरण के लिए जब यह घोषित किया जाता है तो कॉन्स्टेबल वेरिएबल को इनिशियलाइज़ किया जाना चाहिए।
    constint var =25;
    var =50; // gives error

  2. अगर हम अपने पॉइंटर वैरिएबल को क्वालिफाई करते हैं तो उसके बाद हम पॉइंटर को खुद नहीं बदल सकते हैं लेकिन पॉइंटर की सामग्री परिवर्तनशील है । उदा // लेकिनconst *

    int *const ptr = new int;
    ptr = new int; //gives error

    *ptr=5445; //allowed

  3. अगर हम अपने पॉइंटर वैरिएबल को पहले से क्वालीफाई कर लेते हैं तो हम पॉइंटर को खुद ही बदल सकते हैं लेकिन पॉइंटर की सामग्री परिवर्तनशील नहीं है । उदा // लेकिनconst *

    intconst* ptr = new int(85);
    //or
    constint * ptr = new int(85);
    ptr = new int; // allowed

    *ptr=5445; // gives error

  4. सूचक और सामग्री दोनों स्थिर
    उदा
    intconst*constptr = new int(85);
    //or
    constint *constptr = new int(85);
    ptr = new int; // not allowed
    *ptr=5445; // not allowed


  1. Circle copy(const Circle &);
    यहाँ const सर्कल का अर्थ है कि सर्कल का मूल्य केवल पठनीय है, यदि हम सर्कल के मान को फ़ंक्शन के अंदर बदलने का प्रयास करते हैं तो यह त्रुटि देता है।
  2. friend Circle copy(Circle&) const;
    इस प्रकार का फ़ंक्शन नॉन मेंबर वेरिएबल के लिए नहीं है। इसका उपयोग क्लास या स्ट्रक्चर के लिए किया जाता है। यहां संपूर्ण फ़ंक्शन कांस्टेबल कीवर्ड के साथ योग्य है, जिसका अर्थ है कि हम ऑब्जेक्ट सदस्य चर को बदल नहीं सकते हैं । जैसे
    class A{ public :
              int  var;
              void fun1()
                    { var = 50; // allowed
                    } 
              void fun2()const
                       { var=50; //not allowed
                       }
           }; 

4

एक फ़ंक्शन को दूसरे पैरामीटर को संदर्भित करता है।

Circle copy(const Circle &);

इसका मतलब है कि फ़ंक्शन में पारित पैरामीटर को फ़ंक्शन के भीतर नहीं बदला जा सकता है

Circle copy(Circle&) const;

constयोग्य समारोह सदस्य कार्य करता है और इसका मतलब है कि आप वस्तु के ही डेटा सदस्यों को बदल नहीं सकते के लिए प्रयोग किया जाता है। आपके द्वारा पोस्ट किया गया उदाहरण निरर्थक था।

दाएं-बाएं पढ़ें

यदि हम पहले फ़ंक्शन को फिर से लिखते हैं Circle copy(Circle const&);, जिसका अर्थ समान है, तो यह स्पष्ट हो जाता है कि दाएं से बाएं पढ़ना उपयोगी हो जाता है। copyएक फ़ंक्शन है जो constकिसी Circleऑब्जेक्ट के लिए संदर्भ लेता है और Circleसंदर्भ द्वारा ऑब्जेक्ट लौटाता है ।


0

friend Circle copy(const Circle &);// फ़ंक्शन के निरंतर पैरामीटर को संदर्भित करता है। कठबोली 'पैरामीटर द्वारा संग्रहीत मान को बदलते हैं।

अपने उदाहरण में मित्र को हटाने की आवश्यकता है सर्कल कॉपी (सर्कल और) कास्ट; // कॉन्स्टेंट मेंबर फंक्शन के रूप में नामित इस पॉनीटर वैल्यू को बदल नहीं सकते


-1
friend Circle copy(const Circle &);

फ़ंक्शन कॉल के दौरान पैरामीटर का मान नहीं बदला जाएगा।

friend Circle copy(const Circle &)const ; 

फ़ंक्शन एक एक्सेसर है जो क्लास के सदस्यों के किसी भी मूल्य को नहीं बदलता है। आम तौर पर, फ़ंक्शंस के प्रकार होते हैं: एक्सेसर्स और म्यूटेटर। एक्सेसर: जांच करता है लेकिन अपनी वस्तु की स्थिति को नहीं बदलता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.