Ghansham
Ghansham

Reputation: 498

Move Constructor is not getting called

I have written the following code to demonstrate the move construction. But even though I have used std::move(), move constructor is not being invoked. Can someone please see what is the problem here.

#include "point.hpp"
using namespace std;
class point; 
d2point add_point(d2point&& p1, d2point&& p2) 
{ 
 cout << "inside add point function" << endl;
 d2point z;
 z.setX(p1.getX() + p2.getX());
 z.setY(p1.getY() + p2.getY());
 return z;
} 
int main()
{

 d2point x(2,3);
 d2point y(2,3);

 d2point z = add_point(move(x), move(y));
 z.print_point();
 x.print_point();

 return 0;
}

The following is the code from point.hpp

using namespace std;
class point
{
private:
int x;
public:
point(){cout << "point default constructor gets called" << endl;}
point(int x){ cout << "point param constructor gets called" << endl;
this->x = x;
}   

point(const point& p){   
cout << "point copy constructor gets called" << endl;
this->x = p.x;
}   

point(point&& other):x(std::move(other.x)) {
cout << "point move constructor gets called" << endl;
}   

int getX(){return x;} 
void setX(int x) { this->x = x; }

virtual void print_point() {}
virtual ~point(){cout << "point destructor gets called" << endl;}
};

class d2point: public point
{
private:
int y;

public:
d2point()
{   
cout << "d2point default constructor gets called" << endl;
}   

d2point(int x, int y):point(x) {
cout << "d2point parameterized constructor gets called" << endl;
this->y = y;
}   

d2point(const d2point& rhs): point(rhs) {
cout << "d2point copy constructor gets called" << endl;
this->y = rhs.y;
}

d2point(d2point&& rhs):point(std::move(rhs)) {
cout << "d2point move constructor gets called" << endl;
this->y = std::move(rhs.y);
rhs.y = 0;
}

int getY(){return y;}
void  setY(int y) { this->y = y; }

void print_point(){
cout << "(" << getX()  << "," << y << ")" << endl;
}

~d2point(){ cout << "d2point destructor gets called" << endl;}
};

The output of the program is as follows:

point param constructor gets called
d2point parameterized constructor gets called
point param constructor gets called
d2point parameterized constructor gets called
inside add point function
point default constructor gets called
d2point default constructor gets called
(4,6)
(2,3)
d2point destructor gets called
point destructor gets called
d2point destructor gets called
point destructor gets called
d2point destructor gets called
point destructor gets called

Here the function which is taking the rvalue reference is being called, but the move constructor statement is not getting printed, it is really called or some other member function is being invoked. Kindly see the problem here.

Upvotes: 2

Views: 369

Answers (1)

Vittorio Romeo
Vittorio Romeo

Reputation: 93274

The move constructor will not be called unless you're constructing a new instance of d2point from d2point&&. In your add_point function, you're taking rvalue references to d2point: this means that you're not constructing any new instance, but merely refering to existing ones:

d2point add_point(d2point&& p1, d2point&& p2) 
//                       ^^            ^^

Remember that std::move is just a cast to an rvalue reference.

d2point z = add_point(move(x), move(y));

In the line above, you cast both x and y to d2point&& - they get bound to p1 and p2. No construction happened yet. Finally, you store the result of the add_point call into z. Due to return value optimization it is extremely likely that you won't see a move constructor invoked there either.


Changing add_point to

d2point add_point(d2point p1, d2point p2) 

will definitely invoke d2point::d2point(d2point&&).

Upvotes: 5

Related Questions