Digit Digit::operator++(int)
{
// Create a temporary variable with our current digit
Digit cResult(m_nDigit);
// Use prefix operator to increment this digit
++(*this); // apply operator
// return temporary result
return cResult; // return saved state
}
Digit Digit::operator--(int)
{
// Create a temporary variable with our current digit
Digit cResult(m_nDigit);
// Use prefix operator to increment this digit
--(*this); // apply operator
// return temporary result
return cResult; // return saved state
}
int main()
{
Digit cDigit(5);
++cDigit; // calls Digit::operator++();
cDigit++; // calls Digit::operator++(int);
return 0;
}
I am really curious about how the postfix operator works. I see that this code DOES work, but I just do not understand how. I understand that the postfix operator is supposed to evaluate the object, then increment. Could somebody bother to explain to me how the postfix operator differs from the prefix operator, and maybe specifically in this code?
Digit Digit::operator++()
{
++m_nDigit; //Notice no copy is made, which means the digit returned will be incremented.
return *this;
}
The postifix, creates the copy, then increments the original, and then returns the copy. Which means the return value is not incremented, but the next expression that uses the variable (original) will have it's value incremented (just like the copy).
In other words.
1 2 3 4 5 6 7 8 9 10
//...
Digit original(1); //initialize digit to 1.
Digit copy = original++;
//the member m_nDigit is 1, before entering the post fix operator
//(1) First a temp copy of *this is created, where m_nDigit == 1.
//(2) Second the original is incremented (so m_nDigit of "this" is incremented to two).
//(3) Third, the return, returns the temporary Digit variable, which was initialized with m_nDigit == 1 when we did step (1) in this operator.
//(4) Fourth The return value of the operator is copy constructed into Digit copy (which remember is still m_nDigit == 1)
//(5) Fifth, after the ; (line 4 of code) the variable "original" m_nDigit is now 2.
With my bad English I will try to explain. The postfix operator returns current state of the object. For example,
1 2
int x = 10;
int y = x++;
y will have value equal to 10.
Thus in the code
1 2 3 4 5 6 7 8 9 10 11
Digit Digit::operator++(int)
{
// Create a temporary variable with our current digit
Digit cResult(m_nDigit);
// Use prefix operator to increment this digit
++(*this); // apply operator
// return temporary result
return cResult; // return saved state
}
the statements
Digit cResult(m_nDigit);
and
return cResult; // return saved state
provide that the current state of the object will be returned. And the statement
++(*this); // apply operator
does the increment affter the current state of the object is prepared to be returned.
Thanks, your explanation really helped. I'm just wondering why would the incremented result only show up till the next usage of the instance. Are you able to explain?
@vlad from moscow,
Cool! I see that the function returns an unchanged result, but I am still wondering why the object does not increment right when it's called, like the prefix operator form. After all, we increment the class in the function.
I'm just wondering why would the incremented result only show up till the next usage of the instance. Are you able to explain?
Well, technically it's not, it has been incremented, what you are noticing is the return result. The return result is not the original object, it is the copied object.
Let me show you an incorrect implementation:
1 2 3 4 5
Digit operator++(){
++(*this); //increment this first... !!!! wrong in the post fix, should have copied first.
Digit temp(m_nDigit); //Now we copied, but it's already been incremented.
return temp; //we returned temp, which has the increment copied value.
}
Now if you did something like.
1 2
Digit original(1);
Digit value = original++; //value gets initialized with 2, because that is what is returned.
Just by changing when the copy is made, changes the result you see from the returning of the operator call. This incorrect implementation is the exact implementation of the prefix (except that, there is no copy made because it is pointless, what is the copy doing, so we omit it in the prefix implementation like my previous post.)
It is the meaning of the word "postincrement". So firstly the current state of the object is returned and only after that the object is incremented. If for example to change the order of the statements in the function and to write
1 2 3 4 5 6 7 8 9 10 11
Digit Digit::operator++(int)
{
// Use prefix operator to increment this digit
++(*this); // apply operator
// Create a temporary variable with our current digit
Digit cResult(m_nDigit);
// return temporary result
return cResult; // return saved state
}
then we get the state of the object after the increment. So a question arises how to get the state of the object before its increment? So we use the copy constructor
1 2
// Create a temporary variable with our current digit
Digit cResult(m_nDigit);
to make a copy of the current state of the object and after that increment the object itself.
1 2
// Use prefix operator to increment this digit
++(*this); // apply operator
Now we are ready to return the state of the object before the increment
1 2
// return temporary result
return cResult; // return saved state
Okay, I see how the value returns its original class first and makes a copy of the operand class (not a exact copy, but a copy of the value). So the return value become the result of the operand?
Even though the return operand becomes the value of the class increment, the class has the new incremented value, and must be seen in the next usage of the class.
So the return value become the result of the operand?
The return copy of the original object becomes the result of the operator function. While the object itself gets new state that is its state is changed.
As in the example
1 2
int x = 10;
int y = x++;
y gets the copy of the original object x while x itself is changed and its new state will be seen after that statement.
So there is a difference between declaration of the preincrement and postincrement operators.
The preincrement returns reference to the original object
Digit & Digit::operator ++();
while the postincrement operator returns a copy (usually const unnamed object) of the original object before the increment