C++ Tutorial · Advanced C++ · Lesson 19 of 21

C++ Move Semantics

Copy vs move, std::move and the rule of zero.

Copy vs move

Copying a large object duplicates its data. Moving transfers ownership of the internals instead — cheap, and the source is left valid but empty:

Example 1
#include <iostream>
#include <string>
#include <utility>
#include <vector>

int main() {
    std::vector<std::string> a{"alpha", "beta", "gamma"};
    std::vector<std::string> b = a;            // copy
    std::vector<std::string> c = std::move(a); // move: steals a's buffer
    std::cout << a.size() << ' ' << b.size() << ' ' << c.size() << '\n';

    std::string name = "a long string that would be expensive to copy";
    std::vector<std::string> names;
    names.push_back(std::move(name));
    std::cout << names[0].size() << " chars moved; source now " << (name.empty() ? "empty" : "not empty") << '\n';
}

Output

0 3 3
45 chars moved; source now empty

Run this on your computer — see “Get Started” for setup.

The rule of zero

If your class only holds well-behaved members (std::string, std::vector, smart pointers), don't write a destructor, copy or move operations at all — the compiler-generated ones are correct and efficient.

Test yourself

What does std::move actually do?

  1. Copies the object
  2. Casts to an rvalue so the object can be moved from
  3. Deletes the object
  4. Moves memory to the stack
Show answer

Answer: Casts to an rvalue so the object can be moved from