#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;
}
In this program, if I use the chaining functions, values of x and y it comes to be : x=10, y=0 instead of x=10 , y=20
If instead of chaining function, I use:
obj1.setX(10) and obj1.setY(20) separately,
x value comes to be 10
y value comes to 20.
Can someone please explain why it is like this.
Your set* methods are returning copies of the Test object.
So when you chain your calls, the setY is applied to the temporary copy, and thrown away.
You can either return a reference on an object:
Test &setX(int a) { x = a; return *this; }
Test &setY(int b) { x = b; return *this; }
Or to store copy of changed object:
Test obj1;
Test objCopy = obj1.setX(10).setY(20);
objCopy.print();
First is more efficient due to not copying object.
Related
The code given is:
#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;
}
};
Basically I was returning a user-defined object from a member function of the same class.
Test obj1;
obj1.setX(10).setY(24);
obj1.print();
When cpp obj1.setX(10) was executed, was the returned object an lvalue or an rvalue?
If I use the above code, it gives the output as x = 10 y = 0. This got me thinking, is the user-defined object an rvalue or an lvalue, because in the case of primitive data-types (where the function returns a primitive data types) the returned value is an rvalue.
Also, I want to further add that I get the desired output i.e. x = 10 y = 24 if I write,
Test& setX(int a) {
x = a;
return *this;
}
Test& setY(int b) {
y = b;
return *this;
}
Please explain this too.
This question already has answers here:
Multiple dot operator (c++ class)
(1 answer)
Is there a way to call multiple functions on the same object with one line?
(6 answers)
Closed 3 months ago.
I was going through geeksforgeeks and found below code
#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; }
};
This class seems okay for me. But the function call and its output seems bit confusing.
int main()
{
Test obj1;
obj1.setX(10).setY(20);
obj1.print();
return 0;
}
Here, if I call setX() and setY() function in single line, then the output will be:
x = 10 y = 0
else, if I call those function as given below,
int main()
{
Test obj1;
obj1.setX(10);
obj1.setY(20);
obj1.print();
return 0;
}
then the output seems
x = 10 y = 20.
What is the difference between these two function call. Can someone explain using this pointer?
Thankyou in advance.
This question already has answers here:
What is the 'this' pointer?
(8 answers)
Closed 4 years ago.
I confused what does it mean this pointer and how it is used exactly. in the below examples give the same output. What is the difference putting reference operator(&) in the setX and setY functions?
#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;
}
With reference operator
#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;
}
When you return by value, as in
Test setX(int a) { x = a; return *this; }
then you return a copy of the object. And the copy is totally unrelated to the original object.
When you return a reference, you return a reference to the actual object, no copies are made.
And because of this difference the two programs you show should not produce the same output. The first should say that x is equal to 10 (because you set x on the obj1 object) but then you set y on the copy returned by setX, meaning that obj1.y will still be zero. See e.g. this example.
The MWE is
#include <iostream>
using namespace std;
class N {
public:
float x;
N() { x = 0.0; }
N(float a) { x = a; }
//N(N &n) { x = n.x; }
N &operator=(float f) { cout << "########";return *new N(f); }
};
int main() {
N a;
a = 3.0;
cout << a.x;
return 0;
}
What I expect is: it prints 3, but it actually prints 0. It seems the value didn't change.
Then I change it into
x = f; return *this;
It worked, why?
Of course it doesn't change. You don't change it in your assignment operator. Instead you return a pointer to a new value allocated on the heap...and ignore that result.
When returning a reference to the object on which the function is invoked, the returned reference can be used to chain function calls on a single object.
Here, I am applying the same concept. But I am getting different output if I initialize objects differently.
First example:
#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(5, 5);
// Chained function calls. All calls modify the same object
// as the same object is returned by reference
obj1.setX(10).setY(20);
obj1.print();
return 0;
}
Output is 10 and 20, which is correct.
However, output is not correct for the second example:
#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;
}
Output is 10 and 0.
Why? I think both are the same, the output of the second program should be 10 and 20 too. What is the reason it's different?
The difference is that the second version of your program returns by value. This means that the second call (i.e. setY) is performed on a copy of obj1, not on the obj1 itself. That's why only X ends up being set, but not Y.
In your first program, on the other hand, the setters return their results as a reference. This means that no copy is being made, so setY is called on the same object as setX, not on its copy.