Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

assignment operator return a reference to *this in C++

Tags:

c++

I read about this from "Effective c++" ,this is Col.10. It say it's a good way to have assignment operators return a reference to *this. I wrote a code snippet to test this idea. I overridden the assignment operator here.And tested it. Everything is fine. But when I remove that operator overriding, everything is the same. That means, the chaining assignment still works well. So, what am I missing? Why is that? Need some explanation from you guys, THank you.

#include <iostream>

using namespace std;

class Widget{
public:

    Widget& operator=(int rhs)
    {
        return *this;
    }
    int value;

};

int main()
{
    Widget mywidget;
    mywidget.value = 1;
    Widget mywidget2;
    mywidget2.value = 2;
    Widget mywidget3 ;
    mywidget3.value = 3;
    mywidget = mywidget2 = mywidget3;
    cout << mywidget.value<<endl;
    cout << mywidget2.value<<endl;
    cout << mywidget3.value<<endl;

}
like image 525
Don Lun Avatar asked Apr 14 '11 21:04

Don Lun


People also ask

What does the assignment operator return in C?

The assignment operators return the value of the object specified by the left operand after the assignment. The resultant type is the type of the left operand. The result of an assignment expression is always an l-value.

Why do we return reference in copy assignment operator?

If you return a reference, minimal work is done. The values from one object are copied to another object. However, if you return by value for operator= , you will call a constructor AND destructor EACH time that the assignment operator is called!! a = b = c; // calls assignment operator above twice.

Is == an assignment operator?

The “=” is an assignment operator is used to assign the value on the right to the variable on the left. The '==' operator checks whether the two given operands are equal or not.

Which operator is the assignment operator?

The simple assignment operator "=" is used to store the value of its right-hand operand into the memory location denoted by the left-hand operand. The result is its return value.


2 Answers

If you remove completely the operator= method, a default operator= will be created by the compiler, which implements shallow copy1 and returns a reference to *this.

Incidentally, when you write

mywidget = mywidget2 = mywidget3;

you're actually calling this default operator=, since your overloaded operator is designed to work with ints on the right side.

The chained assignment will stop working, instead, if you return, for example, a value, a const reference (=>you'll get compilation errors) or a reference to something different from *this (counterintuitive stuff will start to happen).

Partially related: the copy and swap idiom, i.e. the perfect way to write an assignment operator. Strongly advised read if you need to write an operator=


  1. The default operator= will perform as if there were an assignment between each member of the left hand operand and each member of the right hand one. This means that for primitive types it will be a "brutal" bitwise copy, which in 90% of cases isn't ok for pointers to owned resources.
like image 53
Matteo Italia Avatar answered Oct 12 '22 09:10

Matteo Italia


The question touches two different concepts, whether you should define operator= and whether in doing so you should return a reference to the object.

You should consider the rule of the three: if you define one of copy constructor, assignment operator or destructor you should define the three of them. The rationale around that rule is that if you need to provide a destructor it means that you are managing a resource, and in doing so, chances are that the default copy constructor and assignment operator won't cut it. As an example, if you hold memory through a raw pointer, then you need to release the memory in the destructor. If you don't provide the copy constructor and assignment operator, then the pointer will be copied and two different objects will try to release the memory held by the pointer.

While a pointer is the most common example, this applies to any resource. The exception is classes where you disable copy construction and assignment --but then again you are somehow defining them to be disabled.

On the second part of the question, or whether you should return a reference to the object, you should. The reason, as with all other operator overloads is that it is usually a good advice to mimic what the existing operators for basic types do. This is sometimes given by a quote: when overloading operators, do as ints do.

like image 29
David Rodríguez - dribeas Avatar answered Oct 12 '22 10:10

David Rodríguez - dribeas