Skip to content

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;
}

Content is for learning and research only.