XiaJun
XiaJun

Reputation: 1915

C++ operator= return reference to *this

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):

enter image description here

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 :

enter image description here

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

Answers (7)

perilbrain
perilbrain

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

Mike Seymour
Mike Seymour

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

Grzegorz Herman
Grzegorz Herman

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

jpalecek
jpalecek

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

Alexander Chertov
Alexander Chertov

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

Steed
Steed

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

Alok Save
Alok Save

Reputation: 206546

Usually, You return a reference so that one can use the = operator as an l-value.

Upvotes: 3

Related Questions