2 votes

Le constructeur de mouvement n'est pas appelé

J'ai écrit le code suivant pour démontrer la construction du mouvement. Mais bien que j'aie utilisé std::move(), le constructeur de mouvement n'est pas invoqué. Quelqu'un pourrait-il me dire quel est le problème ?

#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;
}

Voici le code du fichier 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;}
};

La sortie du programme est la suivante :

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

Ici, la fonction qui prend la référence rvalue est appelée, mais la déclaration move constructor n'est pas imprimée, elle est réellement appelée ou une autre fonction membre est invoquée. Je vous prie de bien vouloir comprendre le problème.

4voto

Vittorio Romeo Points 2559

Le constructeur de mouvement ne sera pas appelé à moins que vous ne construisiez une nouvelle instance de d2point de d2point&& . Dans votre add_point vous prenez la fonction rvaleur les références a d2point : cela signifie que vous ne construisez pas de nouvelle instance, mais que vous vous référez simplement à des instances existantes :

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

Rappelez-vous que std::move est juste un cast vers un rvaleur référence .

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

Dans la ligne ci-dessus, vous lancez à la fois x y y a d2point&& - ils sont liés à p1 y p2 . Aucune construction n'a encore eu lieu. Enfin, vous stockez le résultat de l'opération add_point appel en z . En raison de optimisation de la valeur de retour il est très probable que vous ne verrez pas non plus de constructeur de mouvement invoqué à cet endroit.


Changer add_point à

d2point add_point(d2point p1, d2point p2) 

invoquera certainement d2point::d2point(d2point&&) .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X