confusing output
Below given program prints x = 10 y = 0
#include<iostream>
using namespace std;
class Test
{
private:
int x;
int y;
public:
Test (int x = 0, int y = 0) { this->x = x; this->y = y; }
Test setX(int a) { x = a; return *this; }
Test setY(int b) { y = b; return *this; }
void print() { cout << "x = " << x << " y = " << y << endl; }
};
int main()
{
Test obj1;
obj1.setX(10).setY(20);
obj1.print();
return 0;
}
but if we replace
Test setX(int a) { x = a; return *this; }
Test setY(int b) { y = b; return *this; }
with
Test &setX(int a) { x = a; return *this; }
Test &setY(int b) { y = b; return *this; }
output is x = 10 y = 20 Can anyone explain why this is happening?
When you return a plain object rather than a reference, you're returning a copy of the object on which you called the method. setY
acts on that copy (which is a temporary), then the copy is destructed.
When you return a reference, all the calls operate on the same object, so you get the behavior you're looking for.
The first call to setX()
returns a temporary copy of obj1
and the call to setY()
modifies the temporary. Subsequent call to print()
displays the state of obj1
and since in obj1
the y
member variable was never modified it remains zero.
When you replace the return types with references, no temporary copy is made the both calls to setX()
and setY()
operate on obj
.
Lets go back to basis about object oriented programming.
Lets use a metaphor - say a bus.
A bus has certain properties that can be changed - e.g. fuel.
So if you have a function (top up the fuel) you do not need a new bus that is exactly the same as the last one bit with a fuel tank that is full.
So going back to the original question.
Test setX(int a) { x = a; return *this; }
should read
void setX(int a) { x = a; }
etc.
You have the same object but the fuel may be topped up (or x in this case)