Move Semantics
reading
Cyganek section 4.5
What is move semantics? from stackoverflow.
Tip
We are discussing this for completeness, but move semantics can be complicated. I’ll show a “simple” example of a class that manages its own memory and implements move semantics.
C++11 introduced move semantics, which make it possible for objects to
take the data region from one another, instead of having to copy. We
first saw this when we did our orbit integrator and returned a
std::vector
from our function (see More Functions).
For objects that store large data regions, move is much faster than a copy. The C++ compiler will know when it can use a move and automatically do it for you.
Note
This is where the Rule of 3 becomes the Rule of 5: now we consider the (1) copy constructor, (2) assignment operator, (3) destructor, (4) move constructor, (5) move assignment operator. If we write any one of these, we should write all 5.
Right-value references
To allow for move operations, C++11 introduced right-value
references or rvalue references. These use &&
and as the name
suggests, they can appear to the right of the assignment operator,
=
.
Note
&&
here does not mean “reference-to-a-reference”, it is just the
syntax that was chosen for an rvalue reference.
The object that an rvalue reference is a temporary object and it is assumed that it will never be used again, therefore we are free to steal its data. This is sometimes called a destructive read
We can convert an object into an rvalue reference (indicating that it can be moved) via std::move.
Here’s an example where we use the move constructor of a string to steal the data of the input string:
#include <iostream>
#include <string>
int main() {
std::string a{"test"};
std::string steal(std::move(a));
std::cout << "steal = " << steal << " a = " << a << std::endl;
}