C++ Move Semantics

Move semantics in C++ allows the resources of temporary objects (rvalues) to be transferred to another object instead of copying them. This helps improve performance by avoiding unnecessary deep copies, especially for objects that manage dynamic memory or other heavy resources. Move semantics were introduced in C++11.

Key Components

  • Move semantics improves performance by transferring resources instead of copying them.
  • Rvalue references (&&) are used to identify temporary objects.
  • Always set the moved-from object’s pointers to nullptr to avoid double deletion.
  • Move constructors and move assignment operators are automatically used in STL containers like vector when possible.

Next Topic

Next, learn about Operator Overloading in C++.

  • Rvalue references: Declared using && to bind to temporary objects.
  • Move constructor: Transfers resources from a temporary object to a new object.
  • Move assignment operator: Transfers resources from a temporary object to an existing object.

Syntax

class ClassName {
public:
    ClassName(ClassName&& other); // Move constructor
    ClassName& operator=(ClassName&& other); // Move assignment
};

Example: Move Constructor

#include <iostream>
#include <vector>
using namespace std;

class Buffer {
private:
    int size;
    int* data;

public:
    Buffer(int s) : size(s) {
        data = new int[s];
        cout << "Constructor called" << endl;
    }

    // Move constructor
    Buffer(Buffer&& other) noexcept {
        size = other.size;
        data = other.data;
        other.data = nullptr; // Prevent deletion
        cout << "Move constructor called" << endl;
    }

    ~Buffer() {
        delete[] data;
        cout << "Destructor called" << endl;
    }
};

int main() {
    vector<Buffer> vec;
    vec.push_back(Buffer(5)); // Uses move constructor

    return 0;
}

Output

Constructor called
Move constructor called
Destructor called
Destructor called

Example: Move Assignment Operator

#include <iostream>
using namespace std;

class Buffer {
private:
    int size;
    int* data;

public:
    Buffer(int s) : size(s) {
        data = new int[s];
        cout << "Constructor called" << endl;
    }

    // Move assignment operator
    Buffer& operator=(Buffer&& other) noexcept {
        if(this != &other) {
            delete[] data;     // Free existing resource
            size = other.size;
            data = other.data;
            other.data = nullptr;
            cout << "Move assignment called" << endl;
        }
        return *this;
    }

    ~Buffer() {
        delete[] data;
        cout << "Destructor called" << endl;
    }
};

int main() {
    Buffer b1(5);
    Buffer b2(10);

    b2 = move(b1); // Move assignment operator is called

    return 0;
}

Output

Constructor called
Constructor called
Move assignment called
Destructor called
Destructor called

Important Notes

  • Move semantics improves performance by transferring resources instead of copying them.
  • Rvalue references (&&) are used to identify temporary objects.
  • Always set the moved-from object’s pointers to nullptr to avoid double deletion.
  • Move constructors and move assignment operators are automatically used in STL containers like vector when possible.

Next Topic

Next, learn about Operator Overloading in C++.