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.
Related
Problem
I want to create a function inside a class which function2 will use the result generated from function1. I have a small code snippet where I tried to make it easy to understand.
#include <stdio.h>
class GreaterSmaller {
public:
int greater, smaller;
};
GreaterSmaller findGreaterSmaller(int a, int b)
{
GreaterSmaller s;
if (a > b) {
s.greater = a;
s.smaller = b;
}
else {
s.greater = b;
s.smaller = a;
}
return s;
}
GreaterSmaller print()
{
GreaterSmaller s;
std::cout << s.greater << s.smaller << std::endl;
}
int main()
{
int x = 4;
int y = 3;
GreaterSmaller result;
result = findGreaterSmaller(x, y);
result = print(); // I want it to print 4 & 3
return 0;
}
P.s Just wanted to mention I am not trying to print the result in the function2 I have created that for a demo.
Define the second method as taking an argument of the first type, and pass it when you call it, as such:
void print(GreaterSmaller &s)
{
std::cout << s.greater << s.smaller << std::endl;
}
print(result); // I want it to print 4 & 3
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.
I am trying to understand an output of a short program where operator overloading is used.
The output is 137, where the (2+v).print() outputs 13 and 7 is from v.print();
#include <iostream>
using namespace std;
class V
{
int x;
public:
V(int a = 7, int b = 3) { x = a + b; }
void print() { cout << x; }
V operator+(int n)
{
return x++ + ++n;
}
};
V operator+(int lop, V rop)
{
return rop + lop;
}
int main()
{
V v(1, 6);
(2 + v).print();
v.print();
return 0;
}
I understand the basic concept of the operator overloading and I get that V rop is just a copy of the V v(1,6), and it doesn't change the output of v.print(); where x stays 7, but I don't get why it outputs 13, I always get to 10.
The problem is when trying to return an object of type 'V' from this operator:
V operator+(int n)
{
return x++ + ++n;
}
What you're trying to return here in an 'int' so it should be cast to an object of type 'V', the way it's done (casting from a primitive type to custom class) is using constructors. The only constructor you're having is with 2 optional parameters which creates the problem that it tries to make an object of one parameter only, so it's sent as a = 10, b = 3 (default value) and then the output is 13.
I recommend using multiple constructors to solve the problem if you don't want to change the members of the class.
class V
{
int x;
public:
V() { x = 10; }
V(int a) { x = a; }
V(int a, int b) { x = a + b; }
void print() { cout << x; }
V operator+(int n)
{
return x++ + ++n;
}
};
By this way you can call a default constructor which sets x to 10 as you previously did, another constructor with 1 parameter to cast from 'int' to 'V', and your normal constructor that takes a and b.
In your code when arrive at return (x++ + ++n); compiler create an object V so your constructor will be call again. then these assignment will be occurred a=10 and b=3. So you gotta save a and b values in another members.
Try this :
#include <iostream>
using namespace std;
class V {
int x;
int a;
int b;
public:
V(int a=7, int b=3) { x = a + b; this->a = a; this->b = b; }
void print() { cout << x - this->b; }
V operator+(int n) {
return (x++ + ++n);
}
};
V operator+(int lop, V rop) {
return rop + lop;
}
int main()
{
V v(1,6);
(2 + v).print();
v.print();
return 0;
}
Your (2 + v).print(); output will be 10.
#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.
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.