0
class MyClass {
  public:
    ...
    MyClass & operator=(const MyClass &rhs); // return MyClass&
    ...
  }

why not

class MyClass {
  public:
    ...
    MyClass  operator=(const MyClass &rhs); // return MyClass
    ...
  }

Is it the reason that it is more efficient to return by reference in this case?

Thank you

// * updated *

I think I found the key reason as follows:

int i1, it2, i3;
(i1 = i2) = i3; // i3 will be assigned to i1

If the return type of operator= is MyClass rather than MyClass&, then the following statement doesn't perform the same as the internal data type.

MyClass mc1, mc2, mc3;

(mc1 = mc2) = mc3;

It is considered as a good practice by following the rules used by the built-in types.

// *** update ***

#include "stdafx.h"
#include <iostream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    int i1, i2, i3;

    i1 = 0;
    i2 = 2;
    i3 = 3;

    (i1 = i2) = i3;

    cout << "i1: " << i1 << endl;
    cout << "i2: " << i2 << endl;
    cout << "i3: " << i3 << endl;

    return 0;
}

// output from VS2010
/*
i1: 3
i2: 2
i3: 3
*/
q0987
  • 34,938
  • 69
  • 242
  • 387
  • See this similar question: [Overloading assignment operator in C++](http://stackoverflow.com/q/2447696/478288) – chrisaycock Apr 12 '11 at 03:47
  • No, `i3` will not be assigned `i1`. Actually the behavior is undefined in your `(i1 = i2) = i3` assignment. – AnT stands with Russia Apr 12 '11 at 04:34
  • @AndreyT: please see my update2. – q0987 Apr 12 '11 at 18:03
  • I don't understand what specifically you mean by "update 2". But if you are referring to the output you observed in your experiments, then it means absolutely nothing. As I said, *the behavior is undefined*, which means that anything can happen. In your case it produced the illusion if `i1` getting the value of `i3`. But it is just a random illusion. That's what *undefined behavior* means in C++. – AnT stands with Russia Apr 12 '11 at 18:52

3 Answers3

5

What do you mean by your "why not"? It is really up to you. If you want, you can return the copy of the object instead of the reference. There's nothing wrong with that, except that it might indeed prove to be less efficient.

In many cases people prefer to return the reference because it is closer to the semantics of the built-in assignment operator. The built-in operator returns an lvalue, which means that you can write code like

int a, b = 0;
int *p = &(a = b);
// `p` now points to `a`

Admittedly it is not very useful, but still if you want to preserve that lvalue semantics, you need to return a reference from your assignment operator.

Update

Your updated example is incorrect. The (i1 = i2) = i3 expression leads to undefined behavior, not to "i3 will be assigned to i1" as you seem to believe. It is true that the fact that assignment operator returns an lvalue is what allows you to compile expressions like (i1 = i2) = i3. However, this specific expression is useless since the behavior is undefined.

In case of user-defined assignment, as in your (mc1 = mc2) = mc3 example, the behavior is defined but it is still far from being useful. Why would you want to do something like that?

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
1

As long as, operator = receives argument as (const T&), it's a valid operator overloading. You can return whatever value you want. For example, if I want to avoid consecutive object copying, I declare operator as,

void operator = (const T& copy) { }

As soon as you attempt x = y = z; compiler will throw error, but x = y; is still valid! Return value is based on your requirement; if you want you can return the same object or int or char*, it's up to you. Returning non const reference to *this is a popular convention.

iammilind
  • 68,093
  • 33
  • 169
  • 336
  • The argument being a constant reference is not even required... the argument need not be a `const&`, it could be a non-const reference, or even pass by value. As a matter of fact, you can define your own `operator=` to take any type at all (well, the compiler will implicitly define `T& operator=( T const & )` if you don't declare one of `?? operator=( T )`, `?? operator( T& )` or `?? operator=( T const & )` yourself, were `??` is whatever you decide to return. – David Rodríguez - dribeas Apr 12 '11 at 07:58
  • Second @David Rodriguez - dribeas's point, it is incorrect statement that argument should be a const reference. In fact by far the best way of overloading = operator is `copy and swap` mechanism which needs argument to be passed by value. Please read this(http://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap-idiom) and correct your answer. – Alok Save Apr 12 '11 at 08:51
0

My C++ days are long gone, but wouldn't you r syntax create a temporary copy of the class?

hth

Mario

Mario The Spoon
  • 4,799
  • 1
  • 24
  • 36