简体   繁体   中英

Return type of operator= - reference or value?

What is the difference between returning from function "operator="

by reference
by value

? Both version seems to yield a correct result in the example below.

#include <iostream>
using namespace std;

class CComplexNumber{
    float m_realPart;
    float m_imagPart;
public:
    CComplexNumber(float r,float i):m_realPart(r),m_imagPart(i){}

    //the following can be also 
    //CComplexNumber& operator=(const CComplexNumber& orig){
    CComplexNumber operator=(const CComplexNumber& orig){
        if (this!=&orig){
            this->m_realPart=orig.m_realPart;
            this->m_imagPart=orig.m_imagPart;
        }
        return *this;
    }

    friend ostream& operator<<(ostream& lhs,CComplexNumber rhs){
        lhs<<"["<<rhs.m_realPart<<","<<rhs.m_imagPart<<"]"<<endl;
    }
};

int main() {
    CComplexNumber a(1,2);
    CComplexNumber b(3,4);
    CComplexNumber c(5,6);

    a=b=c;
    cout<<a<<b<<c;

    return 0;
}

Returning by value returns a copy of the object. Returning by reference returns the object itself.

Which one you want to use depends on how you want to use the value that was returned. If you want to modify it without affecting the original object (after returning), return by value; otherwise return by reference.

The convention when using the operator= member function is to return by reference. This allows you to chain operations on the object:

CComplexNumber a(1,2);
CComplexNumber b(3,4);

(a = b) *= 2; //Assignment of b to a, then scale by 2

Now, with return by value after the assignment, the *= would not modify the value a , since a copy of a would be scaled by 2. With return by reference, b would be assigned to a and a itself would be scaled by 2.

Returning a reference (mutable) is the least surprising, and what you really should choose for an operation which is so common it is implicitly declared. Reference is the return type of the default/implicit definitions.

Example:

A operator=(const A&) = default; // ERROR
const A& operator=(const A&) = default; // ERROR
A& operator=(const A&) = default; // OK

Some compilers will kindly warn you if you do not return a reference in a user defined function.

In addition to the surprising (and sometimes costly) copy, it also avoids slicing.

Returning a const reference could forbid a move.

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