Reputation: 1915
Look at the following code:
#include <iostream>
using namespace std;
class Widet{
public:
Widet(int val = 0):value(val)
{
}
Widet& operator=(Widet &rhs)
{
value = rhs.value;
return *this;
}
int getValue()
{
return value;
}
private:
int value;
};
int main()
{
Widet obj1(1);
Widet obj2(2);
Widet obj3(0);
(obj3 = obj2) = obj1;
cout << "obj3 = " << obj3.getValue() << endl;
}
The code runs successfully and the output is (using VS2008):
When I let the operator= return a value instead of reference:
Widet operator=(Widet &rhs)
{
value = rhs.value;
return *this;
}
It also runs successfully and the output is :
My question is :Why the second code runs well?Should not we get a error?
Why it is a good habit to return reference to *this instead of *this?
Upvotes: 5
Views: 4128
Reputation: 8197
(obj3 = obj2)
can be considered as obj3operator=(obj2)
//hypothetically.
Since you have passed obj2 as parameter, your operator overload will copy the obj2.value into obj3.value.
(obj3 = obj2) = obj1;
After the return of from operator=
, obj3(*this,temporary copy) will be returned.
So the equivalent code becomes obj3=obj1
which will again invoke operator=
of obj3
and will reset value of obj3.value
to obj1.value
i.e. 1
.
Upvotes: 0
Reputation: 254471
Why the second code runs well?Should not we get a error?
Because it's perfectly valid code. It returns a temporary copy of the object, and you're allowed to call member functions (including operator=()
) on temporary objects, so there is no error.
You would get an error if the object were uncopyable.
Why it is a good habit to return reference to *this instead of *this?
Because not all objects are copyable, and some objects are expensive to copy. You can take a reference to any object, and references are always cheap to pass around.
Upvotes: 8
Reputation: 1915
When you don't return a reference, (obj3 = obj2)
gives a temporary copy of obj3
. The copy obtains the value from obj1
and is deleted, while obje3
is never affected by the second assignment.
Upvotes: 3
Reputation: 47762
Why the second code runs well?Should not we get a error?
It runs because nonconst member functions can be called on (nonconst) class rvalues as well. The second version of operator=
returns a nonconst class rvalue, so in effect, you assign to the temporary, leaving the previous value in the obj3
variable.
Therefore, there is no error.
Upvotes: 2
Reputation: 2108
Returning a reference from operator=() enables expressions like:
a=b=c;
Returning a value may be excessive when you don't need it. It can cause extra copy-constructor/destructor calls. Otherwise, returning a value is perfectly valid C++. People, please correct me if I'm wrong, but I think returning by value is not that big of an issue in C++11 because of move semantics.
Upvotes: 0
Reputation: 1300
In the second example you create a temporary (a copy of Obj3, returned by operator=) and assign Obj1 to it. Then it immediately gets destructed. Obj3 remains the result of first assignment - Obj3 = Obj2
.
Upvotes: 0
Reputation: 206546
Usually, You return a reference so that one can use the =
operator as an l-value.
Upvotes: 3