Как перегрузить оператор ++ двумя разными способами для postfix a++
и префикса ++a
?
Как перегрузить оператор ++ двумя разными способами для postfix a ++ и prefix ++ 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;
}