You can overload the 2 unary operators:
++foo
and foo++
--foo
and foo--
Overloading is the same for both types (++
and --
). Scroll down for explanation
Overloading outside of class
/struct
:
//Prefix operator ++foo
T& operator++(T& lhs)
{
//Perform addition
return lhs;
}
//Postfix operator foo++ (int argument is used to separate pre- and postfix)
//Should be implemented in terms of ++foo (prefix operator)
T operator++(T& lhs, int)
{
T t(lhs);
++lhs;
return t;
}
Overloading inside of class
/struct
:
//Prefix operator ++foo
T& operator++()
{
//Perform addition
return *this;
}
//Postfix operator foo++ (int argument is used to separate pre- and postfix)
//Should be implemented in terms of ++foo (prefix operator)
T operator++(int)
{
T t(*this);
++(*this);
return t;
}
Note: The prefix operator returns a reference to itself, so that you can continue operations on it. The first argument is a reference, as the prefix operator changes the object, that's also the reason why it isn't const
(you wouldn't be able to modify it otherwise).
The postfix operator returns by value a temporary (the previous value), and so it cannot be a reference, as it would be a reference to a temporary, which would be garbage value at the end of the function, because the temporary variable goes out of scope). It also cannot be const
, because you should be able to modify it directly.
The first argument is a non-const
reference to the "calling" object, because if it were const
, you wouldn't be able to modify it, and if it weren't a reference, you wouldn't change the original value.
It is because of the copying needed in postfix operator overloads that it's better to make it a habit to use prefix ++ instead of postfix ++ in for
loops. From the for
loop perspective, they're usually functionally equivalent, but there might be a slight performance advantage to using prefix ++, especially with "fat" classes with a lot of members to copy. Example of using prefix ++ in a for loop:
for (list<string>::const_iterator it = tokens.begin();
it != tokens.end();
++it) { // Don't use it++
...
}