C++ Move Semantics
In this page:
data_type destination = std::move(source); // transfers resources, source is left empty
What is Move Semantics?
Move semantics lets the compiler transfer ownership of a resource -- like heap-allocated memory inside a std::vector or std::string -- from a temporary object directly into a new one, instead of performing a full deep copy.
For large objects, this turns an O(n) copy into an O(1) pointer swap.
Example: What is Move Semantics?
// Include std::cout and std::cin
#include <iostream>
// Include std::vector
#include <vector>
// Program execution starts in main()
int main() {
// Create a vector named source (a resizable array)
std::vector<int> source = {1, 2, 3};
// Create a vector named destination (a resizable array)
std::vector<int> destination = std::move(source);
// Print to the console with cout
std::cout << destination.size() << std::endl;
// Return 0 to signal that the program finished successfully
return 0;
}
Login to try C/C++/Java/PHP code in the editor
The std::move Function
std::move() doesn't physically move any data by itself -- it's purely a cast that tells the compiler "treat this lvalue as an rvalue," making it eligible to be moved from.
The actual transfer of ownership happens inside whatever move constructor or move assignment operator subsequently receives it.
Example: The std::move Function
// Include std::cout and std::cin
#include <iostream>
// Include std::string
#include <string>
#include <utility>
// Program execution starts in main()
int main() {
std::string a = "Hello";
// std::move transfers the resource instead of copying it
std::string b = std::move(a);
// Print to the console with cout
std::cout << b << std::endl;
// Return 0 to signal that the program finished successfully
return 0;
}
Login to try C/C++/Java/PHP code in the editor
Move Constructor
A move constructor takes ownership of a temporary object's internal resources (like a raw pointer to heap memory) by copying that pointer into the new object, then setting the temporary's own pointer to nullptr so its destructor won't accidentally free memory the new object now owns.
Example: Move Constructor
// Include std::cout and std::cin
#include <iostream>
// Define the type Buffer
class Buffer {
// Members below can be accessed from outside the class
public:
int *data;
// Allocate an object on the heap with new
Buffer(int val) { data = new int(val); }
Buffer(Buffer &&other) noexcept {
data = other.data;
other.data = nullptr;
}
~Buffer() { delete data; }
};
// Program execution starts in main()
int main() {
Buffer a(5);
// std::move transfers the resource instead of copying it
Buffer b(std::move(a));
// Print to the console with cout
std::cout << *b.data << std::endl;
// Return 0 to signal that the program finished successfully
return 0;
}
Login to try C/C++/Java/PHP code in the editor
Move Assignment Operator
The move assignment operator first releases whatever resources the target object currently holds (to avoid a leak), then steals the source object's resources the same way a move constructor does -- this is why move assignment is typically written to reuse the move constructor's logic.
Example: Move Assignment Operator
// Include std::cout and std::cin
#include <iostream>
// Define the type Buffer
class Buffer {
// Members below can be accessed from outside the class
public:
int *data;
// Allocate an object on the heap with new
Buffer(int val) { data = new int(val); }
Buffer &operator=(Buffer &&other) noexcept {
// Free the heap memory with delete
delete data;
data = other.data;
other.data = nullptr;
// Send *this back to the caller
return *this;
}
~Buffer() { delete data; }
};
// Program execution starts in main()
int main() {
Buffer a(5), b(10);
// std::move transfers the resource instead of copying it
b = std::move(a);
std::cout << *b.data << std::endl;
return 0;
}
Login to try C/C++/Java/PHP code in the editor
Performance Benefits
For types holding large buffers -- strings, vectors, and similar containers -- move semantics avoids the deep copy those types would otherwise require, which matters most when returning large objects from functions or storing them in containers that resize and relocate elements.
Example: Performance Benefits
// Include std::cout and std::cin
#include <iostream>
// Include std::string
#include <string>
std::string buildGreeting() {
std::string result = "Hello, World!";
// Send result back to the caller
return result;
}
// Program execution starts in main()
int main() {
std::string message = buildGreeting();
// Print to the console with cout
std::cout << message << std::endl;
// Return 0 to signal that the program finished successfully
return 0;
}
Login to try C/C++/Java/PHP code in the editor
- Using an object after moving from it, when its value is unspecified.
- Forgetting
noexcepton move constructors, so containers may copy instead of move. - Trying to move a
constobject, which silently copies.
Chapter Quiz — Complete all 9 topics to unlock
0/9 topics done
Complete these topics first: