116

How can I overload the operator++ in two different ways for postfix a++ and prefix ++a?

2

5 Answers 5

176

Should look like this:

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. } }; 
Sign up to request clarification or add additional context in comments.

16 Comments

This code also shows the prefix vs. postfix performance difference. If the object you are returning doesn't fit into a CPU register, then you are doing an expensive copy operation. This is fine if you need to use the pre-incremented value, but if you don't, postfix is much better. An example would be an iterator where you typically use: for(pos=c.begin(); ...; ++pos) {} instead of pos++
@Eric: You have it correct all the way through apart from a sentence in the middle where you mix. Its prefix that is better.
Why does Number operator++ (int) take an int as a parameter even though you do not use it?
@SeanLetendre: It does not actually take an int parameter. Its a fake parameter. But the designers of the C++ language had to define a way to distinguish between prefix and postfix function definitions. This is the design decision they made.
@EnricoMariaDeAngelis: The syntax distinguishes the two. ++x is prefix and thus calls operator++() while x++ is postfix and thus calls operator++(int)
|
35

The difference lies in what signature you choose for your overload(s) of operator ++.

Cited from the relevant article on this subject in the C++ FAQ (go there for more details):

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

P.S.: When I found out about this, all I saw initially was the dummy parameter, but the different return types are actually more interesting; they might explain why ++x is considered more efficient than x++ in general.

Comments

18

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_oRight 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 two 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.

Comments

1

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).

Comments

-2

I had the same problem and found a simpler solution. Don't get me wrong; this is the same solution as the top one (posted by Martin York). It is just a bit simpler. Just a bit. Here it is:

class Number { public: /* Prefix */ Number& operator++ () { /* Do stuff */ return *this; } /* Postfix */ Number& operator++ (int) { ++(*this); // Using the prefix operator from before return *this; } }; 

The above solution is a bit simpler, because it doesn't use a temporary object in the postfix method.

2 Comments

This is not standard. The postfix operator++ should return what the value was before incrementing, not after.
This answer is incorrect. The temporary is required.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.