0
0
CppConceptIntermediate · 4 min read

What is Move Semantics in C++: Explanation and Example

Move semantics in C++ is a way to transfer resources from one object to another without copying, using rvalue references. It allows efficient management of temporary objects by 'moving' their contents instead of duplicating them.
⚙️

How It Works

Imagine you have a box full of toys and you want to give it to a friend. Instead of making a new box and copying all the toys one by one, you just hand over your box and leave it empty. This is what move semantics does in C++: it transfers ownership of resources like memory or file handles from one object to another without copying.

Normally, when you assign or pass objects, C++ copies all the data, which can be slow for big objects. Move semantics uses a special kind of reference called an rvalue reference (marked by &&) to detect temporary objects that can be 'moved' instead of copied. This saves time and memory by reusing resources.

💻

Example

This example shows a simple class with move constructor and move assignment to transfer ownership of a dynamic array.

cpp
#include <iostream>
#include <utility> // for std::move

class Buffer {
    int* data;
    size_t size;
public:
    Buffer(size_t s) : size(s), data(new int[s]) {
        std::cout << "Constructed buffer of size " << size << "\n";
    }
    
    // Move constructor
    Buffer(Buffer&& other) noexcept : data(nullptr), size(0) {
        data = other.data;
        size = other.size;
        other.data = nullptr;
        other.size = 0;
        std::cout << "Moved buffer of size " << size << "\n";
    }

    // Move assignment
    Buffer& operator=(Buffer&& other) noexcept {
        if (this != &other) {
            delete[] data;
            data = other.data;
            size = other.size;
            other.data = nullptr;
            other.size = 0;
            std::cout << "Move assigned buffer of size " << size << "\n";
        }
        return *this;
    }

    // Destructor
    ~Buffer() {
        delete[] data;
        std::cout << "Destroyed buffer\n";
    }
};

int main() {
    Buffer buf1(5);          // Construct
    Buffer buf2 = std::move(buf1); // Move construct
    Buffer buf3(10);         // Construct
    buf3 = std::move(buf2);  // Move assign
    return 0;
}
Output
Constructed buffer of size 5 Moved buffer of size 5 Constructed buffer of size 10 Move assigned buffer of size 5 Destroyed buffer Destroyed buffer Destroyed buffer
🎯

When to Use

Use move semantics when you want to optimize performance by avoiding unnecessary copying of large or resource-heavy objects. It is especially useful when working with temporary objects, containers like std::vector, or classes managing dynamic memory or system resources.

For example, when returning large objects from functions or transferring ownership of data, move semantics can make your program faster and use less memory. It is a key feature in modern C++ to write efficient and clean code.

Key Points

  • Move semantics transfers resources instead of copying them.
  • It uses rvalue references marked by &&.
  • Move constructors and move assignment operators enable this behavior.
  • It improves performance by avoiding expensive copies.
  • Commonly used with temporary objects and resource-managing classes.

Key Takeaways

Move semantics lets you transfer resources efficiently without copying.
Use rvalue references (&&) to implement move constructors and assignments.
It speeds up programs by reusing resources from temporary objects.
Ideal for classes managing memory or system resources.
Move semantics is essential for modern, efficient C++ code.