I've made this TestClass
to better illustrate the problem. As you can see the move constructor is called when the object is pushed into the vector and when the constructor is initialized using std::move
function. But when we call TestClass testvar2(rvalue_func());
you can see at the end, that the result values of the rvalue_func()
are assigned to testvar2
object, but the move constructor isn't called, also no other constructors or assignment operators were called...
The question: How did it copy the values from rvalue_func()
to testvar2
without calling anything and why the move constructor wasn't called ?
#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;
}
Results:
-------------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
Aucun commentaire:
Enregistrer un commentaire