Как перегрузить оператор ++ двумя разными способами для postfix a ++ и prefix ++ a?

Как перегрузить оператор ++ двумя разными способами для postfix a++ и префикса ++a?

Ответ 1

Должно выглядеть так:

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.
        }
}; 

Ответ 2

Разница заключается в том, какую подпись вы выберете для своей перегрузки (-ей) operator ++.

Процитировано из статьи на эту тему в FAQ по С++ (перейдите туда для получения дополнительной информации):

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

P.S.:. Когда я узнал об этом, все, что я увидел, первоначально было параметром фиктивного типа, но разные типы возвращаемых данных на самом деле более интересны; они могут объяснить, почему ++x считается более эффективным, чем x++ в целом.

Ответ 3

У вас есть два способа перегрузить два (префикс/постфикс) ++ оператора для типа T:

Метод объекта:

Это самый простой способ, используя "общую" идиому ООП.

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 ;
}

Важно помнить, что с точки зрения С++ (включая точку зрения компилятора С++) эти функции, не являющиеся членами, по-прежнему являются частью интерфейса T (если они находятся в одном и том же пространстве имен).

Существует два потенциальных преимущества нотации функций, отличных от членов:

  • Если вам удастся закодировать их, не сделав их друзьями T, то вы увеличили инкапсуляцию T
  • вы можете применить это даже к классам или структурам, код которых у вас нет. Это неинтрузивный способ улучшить интерфейс объекта без изменения его объявления.

Ответ 4

Я знаю это поздно, но у меня была такая же проблема, и я нашел более простое решение. Не поймите меня неправильно, это то же самое решение, что и первое (опубликовано Мартином Йорком). Это немного проще. Самую малость. Вот:

class Number
{
        public:

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

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

Вышеупомянутое решение немного проще, поскольку оно не использует временный объект в методе postfix.

Ответ 5

Объявите так:

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

};

Реализовать правильно - не путайте с тем, что все знают, что они делают (приращение, затем использование, использование затем increment).

Ответ 6

Я хотел бы объяснить это с помощью примера

struct data
{ 
int i; 
};
data operator ++(data x)// pre increment
{
data t;
x.i=x.i+1;
t.i=x.i;
return t;
}
data operator ++ (data x, int ) // post increment ( A dummy int has been passed) 
{ 
data t;
t.i=x.i;
x.i =x.i+1;
return t;
}
void main ()
{
 data i={12}, a;
 a=i++;
 a=++i;
}