简体   繁体   中英

C++ — why the operator= return a reference to *this rather than an object to *this?

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
*/

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?

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.

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

hth

Mario

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM