I'm reading through "SAMS Teach Yourself C++ in 21 days" and I came across an example that I can't seem to understand:
#include<iostream>
using namespace std;
class Counter
{
public:
Counter() {itsVal=0;}
const Counter& operator++ ();
int GetItsVal() {return itsVal;}
private:
int itsVal;
};
const Counter& Counter::operator++()
{
++itsVal;
return *this;
}
int main()
{
Counter i;
Counter a = ++i;
cout << "a: " << a.GetItsVal() << " i: " << i.GetItsVal() << endl;
++a;
cout << "a: " << a.GetItsVal() << " i: " << i.GetItsVal() << endl;
}
Why is there an "&" in the declaration of the ++ operator? I understood this to mean that the return type of the ++ operator was a reference, but it doesn't appear to be a reference to i (since incrementing a does not increment i). I've noticed the code returns the same result if I remove both "&", but maybe it's not as efficient.
Because a reference to the result will be passed out of the function as a reference to the return value, the return value cannot be an automatic variable. in this way, you could use returning reference safely.
A C++ function can return a reference in a similar way as it returns a pointer. When returning a reference, be careful that the object being referred to does not go out of scope. So it is not legal to return a reference to local var. But you can always return a reference on a static variable.
It means you return by reference, which is, at least in this case, probably not desired. It basically means the returned value is an alias to whatever you returned from the function. Unless it's a persistent object it's illegal.
Functions in C++ can return a reference as it's returns a pointer. When function returns a reference it means it returns a implicit pointer.
In C++, when you create a reference, it's a proxy for the original object:
int i = 0;
int& a = i;
++i;
std::cout << i << " " << a << "\n"; // prints '1 1'
++a;
std::cout << i << " " << a << "\n"; // prints '2 2'
Now, in your case:
operator++
returns a reference to the current objectCounter a = ++i;
creates a new object (no &
after Counter
) initialized as a copy of the reference to i
If you wish a
to refer to i
, you need to change its declaration:
Counter& a = ++i;
^
This will fail to compile thought because the return value of Counter::operator++
is Counter const&
: you need to remove the const
here which is non-idiomatic for operator++
and thus:
Counter& Counter::operator++() { ++itsVal; return *this; }
Many functions have commonly observed patterns for their return values and general behavior, allowing you to easily and naturally use them.
Pre-increment and Pre-decrement operators always return a reference to the object after performing their task for chaining:
Counter& Counter::operator++()
Counter& Counter::operator--()
While Post-increment and Post-decrement operators either do not return any value, or a temporary containing the old value for easily copied value-types:
Counter Counter::operator++(int)
Counter Counter::operator--(int)
Or
void Counter::operator++(int)
void Counter::operator--(int)
It looks like in your example someone didn't follow common practice.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With