J'ai fait ce TestClass
pour mieux illustrer le problème. Comme vous pouvez voir le constructeur de mouvement est appelé lorsque l'objet est poussé dans le vecteur et lorsque le constructeur est initialisé en utilisant la fonction std::move
. Mais quand nous appelons TestClass testvar2(rvalue_func());
vous pouvez voir à la fin, que les valeurs de résultat de la rvalue_func()
sont affectés à l'objet testvar2
, mais le constructeur de déplacement n'est pas appelé, aussi aucun autre constructeurs ou opérateurs d'affectation ont été appelés ...c + + 11 déplacer constructeur, initialisation par méthode inconnue en utilisant rvalue
La question: Comment a-t-il copié les valeurs de rvalue_func()
à testvar2
sans rien appeler et pourquoi le constructeur de déplacement n'a pas été appelé?
#include <iostream>
using std::cout;
using std::endl;
#include <vector>
class TestClass {
public:
TestClass(int arg_x=0, int arg_y=0) :
values { nullptr } {
values = new int[2];
values[0] = arg_x;
values[1] = arg_y;
cout << "default constructor " << "x = " << values[0] << " y = "
<< values[1] << endl;
}
TestClass(const TestClass &arg) :
values { nullptr } {
values = new int[2];
values[0] = arg.values[0];
values[1] = arg.values[1];
cout << "copy constructor " << "x = " << values[0] << " y = "
<< values[1] << endl;
}
TestClass(TestClass &&arg) :
values { arg.values } {
arg.values = nullptr;
cout << "move constructor " << "x = " << values[0] << " y = "
<< values[1] << endl;
}
TestClass &operator=(TestClass &right) {
cout << "assignment operator =" << endl;
if (this != &right) {
delete values;
values = nullptr;
values = new int[2];
values[0] = right.values[0];
values[1] = right.values[2];
}
return *this;
}
TestClass &operator=(TestClass &&right) {
cout << "move assignment operator =" << endl;
if (this != &right) {
delete values;
values = right.values;
right.values = nullptr;
}
return *this;
}
void print() {
if (values != nullptr)
cout << "x = " << values[0] << " y = " << values[1] << endl;
}
private:
int *values;
};
TestClass rvalue_func() {
cout << "creating TestClass temp" << endl;
TestClass temp(100, 200);
cout << "TestClass temp is created" << endl;
return temp;
}
void test_rvalues() {
cout << "-------------vector push back--------------" << endl;
std::vector<TestClass> test_vector;
test_vector.push_back(TestClass(1, 2));
cout << "-----rvalue constructor with std::move-----" << endl;
TestClass testvar1(std::move(rvalue_func()));
cout << "------------rvalue constructor-------------" << endl;
TestClass testvar2(rvalue_func());
cout << "-------------------------------------------" << endl;
cout << "testvar2 values ";
testvar2.print();
}
int main(int argc, char *argv[]) {
test_rvalues();
return 0;
}
Résultats:
-------------vector push back--------------
default constructor x = 1 y = 2
move constructor x = 1 y = 2
-----rvalue constructor with std::move-----
creating TestClass temp
default constructor x = 100 y = 200
TestClass temp is created
move constructor x = 100 y = 200
------------rvalue constructor-------------
creating TestClass temp
default constructor x = 100 y = 200
TestClass temp is created
-------------------------------------------
testvar2 values x = 100 y = 200