Move semantics, introduced in C++11, are a key feature that optimizes the performance of C++ programs by allowing the resources of temporary objects to be "moved" rather than copied. This is especially useful for large objects, where copying can be expensive in terms of performance. Move semantics work with a special type of constructor and assignment operator known as the move constructor and move assignment operator.
x + y
, std::string("hello")
).A constructor that "moves" resources from a temporary object (an rvalue) to a new object, leaving the original object in a valid but unspecified state.
Similar to the move constructor, but used for assigning an rvalue to an already existing object.
std::vector
reallocation).Let's start with a simple example where move semantics significantly improve performance.
#include <iostream>
#include <vector>
class MyClass {
public:
int* data;
std::size_t size;
// Constructor
MyClass(std::size_t s) : size(s) {
data = new int[s];
std::cout << "Constructed with size: " << size << std::endl;
}
// Destructor
~MyClass() {
delete[] data;
std::cout << "Destroyed" << std::endl;
}
// Copy Constructor
MyClass(const MyClass& other) : size(other.size) {
data = new int[size];
std::copy(other.data, other.data + size, data);
std::cout << "Copy Constructed" << std::endl;
}
// Move Constructor
MyClass(MyClass&& other) noexcept : data(nullptr), size(0) {
data = other.data;
size = other.size;
other.data = nullptr;
other.size = 0;
std::cout << "Move Constructed" << std::endl;
}
// Copy Assignment Operator
MyClass& operator=(const MyClass& other) {
if (this == &other)
return *this;
delete[] data;
size = other.size;
data = new int[size];
std::copy(other.data, other.data + size, data);
std::cout << "Copy Assigned" << std::endl;
return *this;
}
// Move Assignment Operator
MyClass& operator=(MyClass&& other) noexcept {
if (this == &other)
return *this;
delete[] data;
data = other.data;
size = other.size;
other.data = nullptr;
other.size = 0;
std::cout << "Move Assigned" << std::endl;
return *this;
}
};
int main() {
MyClass obj1(10);
MyClass obj2 = std::move(obj1); // Move construction
MyClass obj3(20);
obj3 = std::move(obj2); // Move assignment
return 0;
}
Standard containers like std::vector
, std::string
, and others leverage move semantics to improve performance during operations like resizing or reallocation.
#include <iostream>
#include <vector>
int main() {
std::vector<MyClass> vec;
vec.reserve(2);
MyClass obj1(10);
vec.push_back(std::move(obj1)); // Uses move constructor
MyClass obj2(20);
vec.push_back(std::move(obj2)); // Uses move constructor
return 0;
}
std::move(obj1)
: Casts obj1
to an rvalue, so vec.push_back()
uses the move constructor instead of the copy constructor.std::vecto
r needs to reallocate its storage, it can move objects to the new storage, improving performance.Move semantics are a cornerstone of modern C++ programming, allowing for more efficient code by eliminating unnecessary copies and enabling resource ownership transfer.
Previous Page | Course Schedule | Course Content