I am working on the class right now
But there is a problem of chain of calling method(here is the code
class Point{
public:
int x;
int y;
Point(int i , int j);
Point incrementX();
Point incrementY();
void print();
};
Point::Point(int i, int j){
x = i;
y = j;
}
Point Point::incrementX(){
x++;
return(*this);
}
Point Point::incrementY(){
y++;
return(*this);
}
void Point::print(){
cout << "(" << x << "," << y << ")" << endl;
}
void Q11(){
Point a(2,3);
//(3,4)
a.incrementX().incrementY().print();
//(3,3)why 33 here ??
a.print();
}
I am confused why the last code a.print()
gives the (3,3)
and I try to print out the address of this
inside the method
I found the two address when calling incrementX()
and incrementY()
is different
My guessing is that incrementX()
access to the class, but when calling incrementY()
the class is occupied. So it make a copy of the class in the heap and then incrementY()
change the y in the copy...
so the (3,4)
is printed by copy, and (3,3)
is printed by actual class...
Your incrementX
and incrementY
functions return by value. That is to say that upon return from those functions your object is copied and so subsequent operations occur on a different instance.
You could see an error occur in compilation were you to delete the copy constructor. To do that add
Point(const Point&) = delete;
(assumes c++11 or greater to use delete
. If older just make it private)
So to diagnose your actual error:
Point
with values (2, 3). incrementX
operates on your original instance (which is now value (3,3)) and passes out a copy on return. incrementY
operates on the temporary copy and updates its value to (3, 4). It also returns a copy.a.print()
displays your original Point
which has not been touched since the call to incrementX
and that displays (3,3).In order to make use of the chaining you wish to use, all of your operations should occur on the same object and to achieve that you should return from those functions by non-const reference.
The function signature
Point Point::incrementX()
becomes
Point& Point::incrementX()
and the complete code looks like.
#include <iostream>
using namespace std;
class Point{
public:
int x;
int y;
Point(int i , int j);
//Point(const Point&) = delete;
Point& incrementX();
Point& incrementY();
void print();
};
Point::Point(int i, int j){
x = i;
y = j;
}
Point& Point::incrementX(){
x++;
return(*this);
}
Point& Point::incrementY(){
y++;
return(*this);
}
void Point::print(){
cout << "(" << x << "," << y << ")" << endl;
}
int main(){
Point a(2,3);
a.incrementX().incrementY().print();
a.print();
}
With the deleted copy constructor this code compiles fine, as no copies are happening.