एक उपप्रकार ++ और उपसर्ग ++ a के लिए दो अलग-अलग तरीकों से ऑपरेटर ++ को कैसे अधिभारित किया जाए?


110

a++उपसर्ग और उपसर्ग के लिए दो अलग-अलग तरीकों से ऑपरेटर ++ को कैसे अधिभारित किया जाए ++a?


1
प्रासंगिक: stackoverflow.com/questions/3181211/…
kennytm

"क्यों वह वाक्यविन्यास" संस्करण: stackoverflow.com/questions/3574831/…
Ciro Santilli 病 ax ax ax

जवाबों:


165

इस तरह दिखना चाहिए:

class Number 
{
    public:
        Number& operator++ ()     // prefix ++
        {
           // Do work on this.   (increment your object here)
           return *this;
        }

        // You want to make the ++ operator work like the standard operators
        // The simple way to do this is to implement postfix in terms of prefix.
        //
        Number  operator++ (int)  // postfix ++
        {
           Number result(*this);   // make a copy for result
           ++(*this);              // Now use the prefix version to do the work
           return result;          // return the copy (the old) value.
        }
}; 

15
यह कोड उपसर्ग बनाम पोस्टफिक्स के प्रदर्शन अंतर को भी दर्शाता है। यदि आपके द्वारा दी जा रही वस्तु सीपीयू रजिस्टर में फिट नहीं होती है, तो आप एक महंगी कॉपी ऑपरेशन कर रहे हैं। यह ठीक है अगर आपको पूर्व-वृद्धित मूल्य का उपयोग करने की आवश्यकता है, लेकिन यदि आप नहीं करते हैं, तो पोस्टफ़िक्स बहुत बेहतर है। एक उदाहरण एक ऐसा इटरेटर होगा जहाँ आप आमतौर पर उपयोग करते हैं: (pos = c.begin (); ...; ++ पॉज़) {} के बजाय pos ++
Eric

22
@ एरिक: आपने इसे बीच में एक वाक्य के अलावा सभी तरह से सही किया है जहाँ आप मिश्रण करते हैं। इसका उपसर्ग जो बेहतर है।
मार्टिन यॉर्क

6
आप इसका उपयोग नहीं करते हुए भी एक पैरामीटर के रूप में क्यों Number operator++ (int)लेते हैं int?
सीन लेटेंडर सेप

10
@ सीनलेन्ट्रे: यह वास्तव में एक अंतर पैरामीटर नहीं लेता है। इसका नकली पैरामीटर है। लेकिन C ++ भाषा के डिजाइनरों को उपसर्ग और पोस्टफिक्स फ़ंक्शन परिभाषाओं के बीच अंतर करने का एक तरीका परिभाषित करना था। यह उनके द्वारा किया गया डिज़ाइन निर्णय है।
मार्टिन यॉर्क

2
@EnricoMariaDeAngelis: वाक्यविन्यास दोनों को अलग करता है। ++xउपसर्ग है और इस प्रकार कहता है operator++() , जबकि x++पोस्टफ़िक्स है और इस तरह कहता हैoperator++(int)
मार्टिन यॉर्क

34

अंतर यह है कि आप अपने ओवरलोड (ओं) के लिए क्या हस्ताक्षर चुनते हैं operator ++

C ++ FAQ में इस विषय पर संबंधित लेख से उद्धृत (अधिक विवरण के लिए वहां जाएं):

class Number {
  public:
    Number& operator++ ();     // prefix ++: no parameter, returns a reference
    Number  operator++ (int);  // postfix ++: dummy parameter, returns a value
};

पुनश्च: जब मुझे इस बारे में पता चला, तो मैंने देखा कि शुरुआत में डमी पैरामीटर था, लेकिन विभिन्न रिटर्न प्रकार वास्तव में अधिक दिलचस्प हैं; वे समझा सकते हैं कि सामान्य++x से अधिक कुशल क्यों माना जाता है ।x++


17

आपके पास दो प्रकार के दो हैं (दो उपसर्ग / पोस्टफिक्स) ++ ऑपरेटर्स टाइप टी के लिए:

वस्तु विधि:

यह "आम" OOP मुहावरे का उपयोग करते हुए सबसे आसान तरीका है।

class T
{
    public :
        T & operator++() // ++A
        {
            // Do increment of "this" value
            return *this ;
        }

        T operator++(int) // A++
        {
           T temp = *this ;
           // Do increment of "this" value
           return temp ;
        }
} ;

गैर-सदस्यीय कार्य:

यह ऐसा करने का एक और तरीका है: जब तक फ़ंक्शन समान नामस्थान में हैं क्योंकि वे जिस ऑब्जेक्ट का भी उल्लेख कर रहे हैं, उन्हें तब माना जाएगा जब कंपाइलर हैंडल ++t ;या t++ ;कोड के लिए एक फेन की खोज करेगा :

class T
{
    // etc.
} ;


T & operator++(T & p_oRight) // ++A
{
   // Do increment of p_oRight value
   return p_oRight ;
}

T operator++(T & p_oRight, int) // A++
{
   T oCopy ;
   // Copy p_oRight into oCopy
   // Do increment of p_oRight value
   return oCopy ;
}

यह याद रखना महत्वपूर्ण है कि, C ++ के दृष्टिकोण से (C ++ संकलक दृष्टिकोण सहित), वे गैर-सदस्य फ़ंक्शन अभी भी T के इंटरफ़ेस का हिस्सा हैं (जब तक वे एक ही नामस्थान में हैं)।

गैर-सदस्य फ़ंक्शन संकेतन के दो संभावित लाभ हैं:

  • यदि आप उन्हें T का मित्र बनाए बिना उन्हें कोड करने का प्रबंधन करते हैं, तो आपने T के एन्कैप्सुलेशन को बढ़ा दिया
  • आप इसे उन कक्षाओं या संरचनाओं पर भी लागू कर सकते हैं जिनके कोड आपके पास नहीं हैं। यह अपनी घोषणा को संशोधित किए बिना किसी ऑब्जेक्ट के इंटरफ़ेस को बढ़ाने के लिए एक गैर-घुसपैठ तरीका है।

1

इस तरह घोषित करें:

class A
{
public:
    A& operator++();    //Prefix (++a)
    A operator++(int); //Postfix (a++)

};

ठीक से लागू करें - हर किसी को पता न चले कि वे क्या करते हैं (वेतन वृद्धि, फिर उपयोग, वेतन वृद्धि)।


-2

मुझे पता है कि यह देर हो चुकी है, लेकिन मुझे एक ही समस्या थी और एक सरल समाधान मिला। मुझे गलत मत समझो, यह शीर्ष एक के रूप में एक ही समाधान है (मार्टिन यॉर्क द्वारा पोस्ट किया गया)। यह थोड़ा सरल है। बस थोड़ा सा। यह रहा:

class Number
{
        public:

              /*prefix*/  
        Number& operator++ ()
        {
            /*Do stuff */
            return *this;
        }

            /*postfix*/
        Number& operator++ (int) 
        {
            ++(*this); //using the prefix operator from before
            return *this;
        }
};

उपरोक्त समाधान थोड़ा सरल है क्योंकि यह पोस्टफ़िक्स विधि में एक अस्थायी वस्तु का उपयोग नहीं करता है।


6
यह मानक नहीं है। पोस्टफ़िक्स ऑपरेटर ++ को वापस लौटना चाहिए जो मूल्य वृद्धि के पहले था, उसके बाद नहीं।
कुइलिन ली जूल 20'18

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