8

There are plenty of codes for explanation on the internet (also specifically here, on stackoverflow) that return *this.

For example from post Copy constructor and = operator overload in C++: is a common function possible? :

MyClass& MyClass::operator=(const MyClass& other)
{
    MyClass tmp(other);
    swap(tmp);
    return *this;
}

When I write swap as:

void MyClass::swap( MyClass &tmp )
{
  // some code modifying *this i.e. copying some array of tmp into array of *this
}

Isn't enough setting return value of operator = to void and avoid returning *this?

Community
  • 1
  • 1
scarface
  • 574
  • 6
  • 20
  • How do you think that chaining assignments like `a = b = c` works? – Some programmer dude Apr 12 '16 at 11:11
  • 2
    the "normal" behavior of `operator =` is to return the reference to the result of the operation. You can define it as void but it behaves different to all users expectations. You simple can not write something like `(x=y)++` or any other evaluation which uses the result value. It is important you return the reference to the object not the value only. If you return only the value, the above term will compile but the result is wrong! – Klaus Apr 12 '16 at 11:12
  • This is called [Method Chaining](https://en.wikipedia.org/wiki/Method_chaining#C.2B.2B). Related: [What does 'return *this' mean in C++?](http://stackoverflow.com/q/18162522/514235). – iammilind Apr 12 '16 at 11:23
  • 2
    I would consider this as good introductory interview question. – SChepurin Apr 12 '16 at 11:35

3 Answers3

11

This idiom exists to enable chaining of function calls:

int a, b, c;
a = b = c = 0;

This works well for ints, so there's no point in making it not work for user defined types :)

Similarly for stream operators:

std::cout << "Hello, " << name << std::endl;

works the same as

std::cout << "Hello, ";
std::cout << name;
std::cout << std::endl;

Due to the return *this idiom, it is possible to chain like the first example.

Magnus Hoff
  • 21,529
  • 9
  • 63
  • 82
7

One of reasons why *this is returned to allow assignment chains like a = b = c; which is equivalent to b = c; a = b;. In general, result of assignment could be used anywhere, e.g. when invoking functions (f(a = b)) or in expressions (a = (b = c * 5) * 10). Although, in most cases, it just makes code more complicated.

George Sovetov
  • 4,942
  • 5
  • 36
  • 57
1

you return *this when there is a strong sense that you will invoke yet the same action on the object.

for example, std::basic_string::append return itself because there is a strong sense that you will want to append yet another string

str.append("I have ").append(std::to_string(myMoney)).append(" dollars");

the same goes for the operator =

myObj1 = myObj2 = myObj3

swap doesn't has this strong sense. does the expression obj.swap(other).swap(rhs) seems common?

David Haim
  • 25,446
  • 3
  • 44
  • 78