C++ Move Semantics
Overview
Move semantics allow efficient transfer of resources from temporary objects, avoiding unnecessary copies.
rvalue References
Basic rvalue References
cpp
#include <iostream>
#include <utility>
void printReference(int& x) {
std::cout << "Lvalue reference: " << x << std::endl;
}
void printReference(int&& x) {
std::cout << "Rvalue reference: " << x << std::endl;
}
int main() {
int a = 10;
printReference(a); // Calls lvalue version
printReference(20); // Calls rvalue version
printReference(a + 5); // Calls rvalue version
return 0;
}Move Constructor and Move Assignment
Implementing Move Semantics
cpp
#include <iostream>
#include <utility>
class DynamicArray {
private:
int* data;
size_t size;
public:
// Constructor
DynamicArray(size_t s) : size(s), data(new int[s]) {
std::cout << "Constructor called" << std::endl;
}
// Destructor
~DynamicArray() {
delete[] data;
std::cout << "Destructor called" << std::endl;
}
// Copy constructor
DynamicArray(const DynamicArray& other) : size(other.size), data(new int[other.size]) {
std::copy(other.data, other.data + other.size, data);
std::cout << "Copy constructor called" << std::endl;
}
// Move constructor
DynamicArray(DynamicArray&& other) noexcept : data(other.data), size(other.size) {
other.data = nullptr;
other.size = 0;
std::cout << "Move constructor called" << std::endl;
}
// Copy assignment
DynamicArray& operator=(const DynamicArray& other) {
if (this != &other) {
delete[] data;
size = other.size;
data = new int[other.size];
std::copy(other.data, other.data + other.size, data);
}
std::cout << "Copy assignment called" << std::endl;
return *this;
}
// Move assignment
DynamicArray& operator=(DynamicArray&& other) noexcept {
if (this != &other) {
delete[] data;
data = other.data;
size = other.size;
other.data = nullptr;
other.size = 0;
}
std::cout << "Move assignment called" << std::endl;
return *this;
}
};
DynamicArray createArray() {
DynamicArray arr(1000);
return arr; // Return value optimization / move
}
int main() {
DynamicArray arr1(1000);
DynamicArray arr2 = arr1; // Copy constructor
DynamicArray arr3 = std::move(arr1); // Move constructor
DynamicArray arr4 = createArray(); // Move constructor
arr2 = arr3; // Copy assignment
arr2 = std::move(arr4); // Move assignment
return 0;
}std::move
Explicit Move
cpp
#include <iostream>
#include <utility>
#include <vector>
int main() {
std::vector<int> vec1 = {1, 2, 3, 4, 5};
std::vector<int> vec2;
// Move instead of copy
vec2 = std::move(vec1);
std::cout << "vec1 size: " << vec1.size() << std::endl; // 0
std::cout << "vec2 size: " << vec2.size() << std::endl; // 5
return 0;
}