-2

In assignment operator overloading, If I return the object by reference like below

One& operator=( const One&  obj).

Then program works fine.

But if when I return by value, like below

One operator=( const One&  obj)

Then o1 gets garbage value. Can anybody explain why return by value does not work in assignment operator overloading?

class One
{
    public:
        One(int a1, int b1) {  
            a = a1; b = b1; 
        }

        int a;
        int b;
        One operator=( const One&  obj) { 
            cout<<"\nOperator= is called\n"; a = obj.a; b = obj.b; 
        }
};


int main()
{
    One o1(5,5);
    One o2(10,10);
    One o3(15,15);

    cout << "\no1.a=" << o1.a << ", o1.b=" << o1.b << endl;

    o1 = o2 = o3;

    cout << "\no1.a=" <<o1.a << ", o1.b=" << o1.b << endl;
    cout << "\no2.a=" <<o2.a << ", o2.b=" << o2.b << endl;
    cout << "\no3.a=" <<o3.a << ", o3.b=" << o3.b << endl;


    return 0;
}

Output:

o1.a=-13360, o1.b=0

o2.a=15, o2.b=15

o3.a=15, o3.b=15

Why o1 object showing garbage value in case of return by value in assignment operator. It works fine when return by reference. why?

Alexey Subach
  • 9,378
  • 7
  • 29
  • 54
Gaurav
  • 161
  • 11
  • 8
    You never return anything from your `operator =`. Also the code you show does not match the signature you have in the question – NathanOliver Feb 07 '17 at 13:01
  • 1
    Just a FYI: Since your class is a POD type there is no reason for you to write a copy assignment operator. The compiler will provide it for you. – NathanOliver Feb 07 '17 at 13:09

3 Answers3

2

o1 = o2 = o3; is evaluated as o1 = (o2 = o3);

That requires o2 = o3 to return something, and o1 is set to that value. But your overload currently doesn't. (Formally it means that the behaviour of your code is undefined). If you rewrite to

 One& operator=(const One& obj)
 {
     std::cout << "\nOperator= is called\n";
     a = obj.a;
     b = obj.b;
     return *this; // i.e. return a reference to self.
 }

then all will be well. That said, the cool cats will use

 One& operator=(One obj/*pass by value to exploit compiler optimisations*/)
 {
     std::cout << "\nOperator= is called\n";
     std::swap(*this, obj);
     return *this;
 }

Reference: What is the copy-and-swap idiom?

Community
  • 1
  • 1
Bathsheba
  • 220,365
  • 33
  • 331
  • 451
1

The code of the = operator should be this:

One & operator=(const One&  obj)
{
  cout << "\nOperator= is called\n";
  a = obj.a;
  b = obj.b;
  return *this;
}
Jabberwocky
  • 40,411
  • 16
  • 50
  • 92
  • That is fine, Thanks for that. Then how is it working for One&? As in case of One& Return type also, I am not returning anything. – Gaurav Feb 07 '17 at 13:04
  • You need to return something from an assignment operator if you want `o1 = o2 = o3;` which is actually `o1 = (o2 = o3);` to work. – Jabberwocky Feb 07 '17 at 13:05
  • 1
    @Gaurav It is called undefined behavior. It may or may not work but it is definitely not correct. – NathanOliver Feb 07 '17 at 13:06
  • Thanks Michael. I was confused why it was working for One&. Actually it seems undefined behavior in case of not returning any value. Thanks again – Gaurav Feb 07 '17 at 13:07
  • @NathanOliver, Thanks mate. I got it now. – Gaurav Feb 07 '17 at 13:08
0
 One operator=( const One&  obj)
 { cout<<"\nOperator= is called\n"; a = obj.a; b = obj.b; }

You do not have any return expression in your function definition, resulting in undefined behavior. That's why the operator does not work as it should.

In case you are using the gcc compiler, I would suggest you enable the -Wall option, which would have produced a warning, indicating the failure. In case you are using sth different there's probably an equivalent option available.

You may also want to take a look at the Copy-and-Swap Idiom which provides an advanced insight in the creation of a properly working copy-assignment operator.

Community
  • 1
  • 1
SebNag
  • 903
  • 9
  • 27