I saw this C++ code as part of a larger example:
Date &Date::operator++()
{
helpIncrement();
return *this;
}
Date Date::operator++( int )
{
Date temp = *this;
helpIncrement();
return temp;
}
Firstly if Date temp = *this
, then I dont see why the return type is any different for these two functions? One returns *this
, the other returns temp
, which is assigned to *this
?
Secondly, why does the parameter for the second function not have a variable name?
The first returns the object pointed to by this
as a reference. That is, the returned object is the object that operator++
is being called on. However, when you do Date temp = *this
, temp
is copy constructed from the value of *this
. It is in turn then copied out of the function. What you get from the second function is a whole new object. Why the functions have this difference is explained in the answer to your second question.
There are two types of increment operator - one is post-increment ( i++
) and the other is pre-increment ( ++i
). To be able to overload each of them individually (despite them having the same name, operator++
), the C++ standard specifies that the post-increment operator takes an argument of type int
with unspecified value. This is simply so that you can overload the function for each use of the operator. Since you're unlikely to want to use that unspecified value, you may as well just leave it unnamed.
Now, the expected behaviour of the pre-increment operator is that it increments the object and evaluates to then be that object. That's why it returns a reference in this case. The expected behaviour of post-increment is that it keeps a copy of the original value, increments the object and then returns the original value. Hence, it returns the temp
copy.
This is an excellent question - it highlights a rather silly design choice the designers of C++ took:
int
parameter is post-increment. int
parameter is added for a single reason - distinguishing between the two overloads; it is otherwise meaningless, that is why its value is never used. The first operator is pre-increment: it increments the value, and returns the result. The second is post-increment: it increments the value, and returns the previous value. In that code, temp
holds the previous value, helpIncrement()
increments the value, and the previous value ( temp
) is returned. The reason the argument doesn't have a name is that it isn't used. That's a bit of a hack; the compiler knows that ++my_value
should get translated into my_value.operator++()
, and that my_value++
should get translated into my_value.operator++(1)
. That is, the absence or presence of an integral argument determines which overload to call.
The first function returns reference to this, after it was incremented. The second one returns a copy of this, before it was incremented.
The unused parameter in the second function distinguishes between prefix (no parameter) and postfix (single int
parameter) versions of ++ operator.
This is a basic topic, read about overloading operator++
. You can start here: Operator overloading
Firstly if Date temp = *this, then I dont see why the return type is any different for these two functions?
Let's compare this with the situation of ++
on good old int
. Consider
int i = 1;
int j = i++;
After this, j
holds the old value of i
, but i
itself is incremented. So i
must have been copied prior to the increment, as if ++
on int
were defined as
class int { // pseudocode
public:
int operator++(int)
{
int temp = *this;
*this += 1;
return temp;
}
};
OTOH, after
int i = 1;
int j = ++i;
i
and j
have the same value, so ++
must have been implemented as
int &operator()
{
*this += 1;
return *this;
}
where the change from int
to int&
introduces convenience: there's no need to make a copy and it's possible to use ++i
in a situation where a reference is needed.
Secondly, why does the parameter for the second function not have a variable name?
Because it should never be used. The argument is there as a syntactic gimmick so the compiler can distinguish the two types of operator++
(pre- and post-increment) from each other, but it doesn't have any well-defined value. Giving it a name would trigger an "unused identifier" option in a compiler with proper warnings enabled.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.