Postfix operator overloading

May 15, 2011 at 5:59am
Hi, I was going across a tutorial on http://newdata.box.sk/bx/c/htm/ch10.htm
And I got this program as an example to demonstrate operator overloading :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
1:     // Listing 10.12
2:     // Returning the dereferenced this pointer
3:
4:     typedef unsigned short  USHORT;
5:     #include <iostream.h>
6:
7:     class Counter
8:     {
9:     public:
10:       Counter();
11:       ~Counter(){}
12:       USHORT GetItsVal()const { return itsVal; }
13:       void SetItsVal(USHORT x) {itsVal = x; }
14:       const Counter& operator++ ();      // prefix
15:       const Counter operator++ (int); // postfix
16:
17:    private:
18:       USHORT itsVal;
19:    };
20:
21:    Counter::Counter():
22:    itsVal(0)
23:    {}
24:
25:    const Counter& Counter::operator++()
26:    {
27:       ++itsVal;
28:       return *this;
29:    }
30:
31:    const Counter Counter::operator++(int)
32:    {
33:       Counter temp(*this);
34:       ++itsVal;
35:       return temp;
36:    }
37:
38:    int main()
39:    {
40:       Counter i;
41:       cout << "The value of i is " << i.GetItsVal() << endl;
42:       i++;
43:       cout << "The value of i is " << i.GetItsVal() << endl;
44:       ++i;
45:       cout << "The value of i is " << i.GetItsVal() << endl;
46:       Counter a = ++i;
47:       cout << "The value of a: " << a.GetItsVal();
48:       cout << " and i: " << i.GetItsVal() << endl;
49:       a = i++;
50:       cout << "The value of a: " << a.GetItsVal();
51:       cout << " and i: " << i.GetItsVal() << endl;
52:     return 0;
53: }

Output: The value of i is 0
The value of i is 1
The value of i is 2
The value of a: 3 and i: 3
The value of a: 3 and i: 4


I do not understand how the function for overloading the postfix++ operator works here - lines 31-36

More specifically this line:Counter temp(*this);
What does this line do?Is temp() a built in function?

May 15, 2011 at 6:49am
Counter temp(*this); is creating a new object named temp by calling the copy ctor.

It's the same as saying this: Counter temp = *this;

or this: Counter temp = Counter(*this);
Jun 4, 2011 at 3:46am
what I don't understand here is that since we are calling ++ on an object and we have overloaded it, how does compiler know that it has to call the postfix function for a = i++; and prefix function for a = ++i;. can anyone please explain
Jun 4, 2011 at 3:51am
What do you mean how does it know? It knows to call postfix when the ++ is after the object name, and prefix when it is before it.
Jun 4, 2011 at 9:10am
1
2
3
4
5
6
7
8
9
10
11
12
13
class Object {
   //...
 public:
   Object operator++();
   Object operator++(int);
} obj;
//...

++obj; //is equivalent to
obj.operator++();

obj++; //is equivalent to
obj.operator++(0);
Last edited on Jun 4, 2011 at 9:11am
Jun 4, 2011 at 12:20pm
let me elaborate my question. In the case of primitives it is clear the ++ before the primitive is treated as prefix and after the primitive is treated as postfix. But this is a user defined object. We have defined two functions operator++ . How does compiler brand one as "prefix" and other as "postfix"?
or
why are these true?
1
2
++obj; //is equivalent to
obj.operator++();


1
2
obj++; //is equivalent to
obj.operator++(0);

Last edited on Jun 4, 2011 at 12:27pm
Jun 4, 2011 at 3:03pm
Look carefully at the function signatures..
1
2
3
4
5
6
7
8
9
10
11
12
25:    const Counter& Counter::operator++() //PREFIX - notice that this one takes no parameters
26:    {
27:       ++itsVal;
28:       return *this;
29:    }
30:
31:    const Counter Counter::operator++(int) //POSTFIX - this one  has an UNUSED dummy int parameter.
32:    {
33:       Counter temp(*this);
34:       ++itsVal;
35:       return temp;
36:    }


When the compiler needs the postfix ++ function - it uses the one which has been defined to take an int parameter.
( It does not actually use the parameter though)

The same thing applies to the decrement operator --.
Last edited on Jun 4, 2011 at 3:11pm
Jun 4, 2011 at 9:07pm
please look carefully at my question. how does compiler know to call operator++(int) when you say itsVal++.
Jun 4, 2011 at 9:31pm
I don't think we're understanding your question, because the answer seems plainly obvious.

In the case of primitives it is clear the ++ before the primitive is treated as prefix and after the primitive is treated as postfix


It is exactly the same for objects.

But this is a user defined object.


That doesn't matter. If the ++ is before the object name, it uses prefix. If it's after, it uses postfix.

How does compiler brand one as "prefix" and other as "postfix"?


The C++ standard says that if it has a dummy int parameter, it's a postfix operator. If no dummy int parameter, then it's the prefix operator.
Jun 4, 2011 at 9:45pm
ok, so the answer is that the compiler has the same signature for a prefix and postfix operators for the user-defined objects as for the primitive objects. So, I cannot have a function like operator++(float). Thanks guys! I understand it now
Last edited on Jun 4, 2011 at 9:46pm
Jul 17, 2011 at 10:28am
On a slightly related topic, how does one make i++++ work?
With the code from above, the compiler complains: passing const Counter as this argument of const Counter& Counter::operator++() discards qualifiers
Getting rid of the Const solves that but when using a = ++++i; and a = i++++; the output is
1
2
3
4
5
The value of i is 0
The value of i is 1
The value of i is 2
The value of a: 4 and i: 4
The value of a: 4 and i: 5

when the last line should be The value of a: 4 and i: 6
Jul 18, 2011 at 1:49pm
i += 2;
You can't/shouldn't use more then one ++ or -- operator in a single expression because there is no standard to declare in what order the operators must evaluate.
Jul 18, 2011 at 6:27pm
if you overload an unary operator with no arguments, compiler does prefix,
with an argument, it does postfix. any kind of argument will be a sign to the compiler to do postfix.
Last edited on Jul 18, 2011 at 6:28pm
Topic archived. No new replies allowed.