Skip to content
  • Move Semantics & rvalue References · C++

Move Semantics & rvalue References

LearnViaNotes @learnvianotes· 3 min read

Moving transfers a resource from an object that's about to die (or that you no longer need) instead of copying it. A std::vector move is three pointer copies — no matter how many elements it holds.

Copy vs move

C++
#include <iostream>
#include <string>
#include <utility>
#include <vector>

int main() {
    std::vector<int> a(1'000'000, 7);
    std::vector<int> b = a;               // copy: allocates and copies a million ints
    std::vector<int> c = std::move(a);    // move: steals a's buffer
    std::cout << a.size() << ' ' << b.size() << ' ' << c.size() << '\n';   // a is now empty (valid, unspecified)

    std::string s = "a fairly long string that will not fit in SSO";
    std::vector<std::string> names;
    names.push_back(s);                   // copies
    names.push_back(std::move(s));        // moves — s is left valid but unspecified
    std::cout << names.size() << ' ' << names[1].size() << '\n';
}
Output
0 1000000 1000000
2 45

Writing move operations

C++
#include <iostream>
#include <utility>

class Buffer {
    int* data_ = nullptr;
    std::size_t size_ = 0;
public:
    explicit Buffer(std::size_t n) : data_(new int[n]{}), size_(n) {}
    ~Buffer() { delete[] data_; }

    Buffer(const Buffer& o) : data_(new int[o.size_]), size_(o.size_) {
        std::copy(o.data_, o.data_ + size_, data_);
        std::cout << "copy\n";
    }
    Buffer(Buffer&& o) noexcept                                        // move constructor
        : data_(std::exchange(o.data_, nullptr)), size_(std::exchange(o.size_, 0)) {
        std::cout << "move\n";
    }
    Buffer& operator=(Buffer&& o) noexcept {                           // move assignment
        if (this != &o) {
            delete[] data_;
            data_ = std::exchange(o.data_, nullptr);
            size_ = std::exchange(o.size_, 0);
        }
        return *this;
    }
    Buffer& operator=(const Buffer&) = delete;   // kept short for the example
    std::size_t size() const { return size_; }
};

Buffer make() { return Buffer(8); }             // guaranteed elision: no copy, no move

int main() {
    Buffer a(4);
    Buffer b = std::move(a);        // move
    Buffer c = b;                   // copy
    Buffer d = make();              // nothing printed
    d = std::move(c);               // move assignment
    std::cout << a.size() << ' ' << b.size() << ' ' << c.size() << ' ' << d.size() << '\n';
}
Output
move
copy
0 4 0 4
  1. Steal

    Take the source's pointers/handles.

  2. Reset the source

    Leave it in a valid, destructible state (usually empty) — std::exchange(o.p, nullptr) does both in one step.

  3. Mark noexcept

    std::vector only moves elements during reallocation if the move constructor is noexcept; otherwise it copies to keep the strong guarantee.

Why noexcept matters

C++
#include <iostream>
#include <vector>
struct Safe   { Safe() = default;   Safe(const Safe&)   { std::cout << "C"; } Safe(Safe&&) noexcept { std::cout << "M"; } };
struct Unsafe { Unsafe() = default; Unsafe(const Unsafe&) { std::cout << "C"; } Unsafe(Unsafe&&)       { std::cout << "M"; } };
int main() {
    std::vector<Safe> a(2);
    a.reserve(10);             // reallocation moves the 2 elements
    std::cout << '\n';
    std::vector<Unsafe> b(2);
    b.reserve(10);             // reallocation copies — the move might throw
    std::cout << '\n';
}
Output
MM
CC

Pitfalls

  • std::move only casts; if the type has no move constructor, the copy constructor is used.

  • Don't use a moved-from object except to assign to it or destroy it (standard types guarantee “valid but unspecified”).

  • return std::move(local); prevents copy elision — just return local; (it's moved automatically if not elided).

  • const objects can't be moved from: std::move(constObj) yields const T&&, which binds to the copy constructor.

What is an rvalue reference?

Why should move constructors be noexcept?

Free for students and teachers

Write notes like this one

Cards for every idea, quizzes and flashcards, read aloud — on the web and your phone.

Something wrong with this note? Open it to report