How can I overload operator++ in two different ways (for a++ and ++a)?
views:
151answers:
5The difference lies in whether you define a operator ++ without or with a (dummy) parameter.
Cited from the relevant article on this subject in the C++ FAQ (go there for more details):
class Number { public: Number& operator++ (); // prefix ++ Number operator++ (int); // postfix ++ };
Declare like so:
class A
{
public:
A& operator++(); //Prefix (++a)
A operator++(int); //Postfix (a++)
};
Implement properly - do not mess with what everyone knows they do (increment then use, use then increment).
Should look like this:
class Number
{
public:
Number& operator++ () // prefix ++
{
// Do work on this.
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.
}
};
You have two ways to overload the two (prefix/postfix) ++ operators for a type T:
Object method:
This is the easiest way, using "common" OOP idiom.
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 ;
}
} ;
Object non-member function:
This is another way to do this: As long as the functions are in the same namespace as the object they are referring too, they will be considered when the compiler will search for a fonction to handle ++t ; or t++ ; code:
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_oRigh value
return oCopy ;
}
It is important to remember that, from a C++ viewpoint (including a C++ compiler viewpoint), those non-member functions are still part of T's interface (as long as they are in the same namespace).
There are too potential advantages of the non-member function notation:
- If you manage to code them without making them friend of T, then you increased the encapsulation of T
- you can apply this even to classes or structures whose code you don't own. This is a non-intrusive way to enhance the interface of an object without modifying its declaration.