I was trying to move an instance to another one, as follows:
#include <iostream>
class student {
public:
student() = default;
student(const student& student) {
std::cout << "copy student" << std::endl;
}
student(student&& student) {
std::cout << "move student" << std::endl;
}
virtual ~student() = default;
};
class undergraduate: public student {
public:
undergraduate(): student() {}
~undergraduate() override = default; // removing this line will make std::move work
};
int main() {
undergraduate student;
undergraduate student1 = std::move(student);
}
Here is the output:
copy student
As you can see, std::move
didn't work, student
was copied instead of moved, however, if I remove undergraduate
's destructor, i.e. the following line:
~undergraduate() override = default; // removing this line will make std::move work
The output will become move student
, which means std::move
works. Why? Why didn't std::move
work when the derived class' destructor is specified?
uninitialized_move() initializes new T objects into the new memory area by moving them from the old memory area. Then it calls the destructor on the original T object, the moved-from object.
std::move is used to indicate that an object t may be "moved from", i.e. allowing the efficient transfer of resources from t to another object. In particular, std::move produces an xvalue expression that identifies its argument t . It is exactly equivalent to a static_cast to an rvalue reference type.
std::move is actually just a request to move and if the type of the object has not a move constructor/assign-operator defined or generated the move operation will fall back to a copy.
Specifying a class's destructor inhibits automatic generation of the move constructor and move assignment. You can restore them by using = default
:
class undergraduate: public student {
public:
undergraduate(): student() {}
~undergraduate() override = default;
undergraduate(const undergraduate&) = default;
undergraduate& operator=(const undergraduate&) = default;
undergraduate(undergraduate&&) = default;
undergraduate& operator=(undergraduate&&) = default;
};
Howard Hinnant created an excellent table for his Everything You Ever Wanted To Know About Move Semantics (and then some)" presentation:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With