I am confused when all the code I find shows returning a reference variable when overloading the prefix operator. I went through the parashift.com FAQ (http://www.parashift.com/c++-faq-lite/operator-overloading.html#faq-13.14) and it isn't clear, even though it says it WILL be clear when you read it. I adapted their example into a nonsensical, pointless little program to test.
#include<iostream>
using namespace std;
class Number {
public:
Number& operator++ (); // prefix ++
Number operator++ (int); // postfix ++
int value() { return value_; }
void setValue(int value) { value_ = value; }
private:
int value_;
};
Number& Number::operator++ () {
++value_;
return *this;
}
Number Number::operator++ (int unused) {
Number temp;
temp.setValue(value_);
++value_;
return temp;
}
int main()
{
Number someNum;
someNum.setValue(20);
cout << "someNum : " << someNum.value() << "\n";
someNum++;
++someNum;
cout << "someNum : " << someNum.value() << "\n";
return 0;
}
The problem is, it works if I just declare it as a Number object as well like so:
#include<iostream>
using namespace std;
class Number {
public:
Number operator++ (); // prefix ++
Number operator++ (int); // postfix ++
int value() { return value_; }
void setValue(int value) { value_ = value; }
private:
int value_;
};
Number Number::operator++ () {
++value_;
return *this;
}
Number Number::operator++ (int unused) {
Number temp;
temp.setValue(value_);
++value_;
return temp;
}
int main()
{
Number someNum;
someNum.setValue(20);
cout << "someNum : " << someNum.value() << "\n";
someNum++;
++someNum;
cout << "someNum : " << someNum.value() << "\n";
return 0;
}
I assume I simply need a better understanding of reference variables. Can anyone explain simply why the prefix operator SHOULD be coded as returning a reference variable?
First, there's an efficiency issue. You are creating a new instance of the class in order to return it for no reason.
Second, there's the semantic issue. Your code invokes the empty constructor or the copy constructor to make the temporary and then destructs the temporary. If that has semantic meaning that's inappropriate, then the code doesn't really work, it just appears to.
Third, the code returns the wrong thing. Consider: ++foo.do_something();
. With your code, we call 'do_something' on the temporary object. We wanted to call do_something()
on the pre-incremented foo
.