C/C++ Arena

Step 2 of 7

Write a move constructor

How does a class become movable? It provides a move constructor: a constructor that takes an rvalue reference, written T&&. An && parameter only binds to rvalues (temporaries and std::moved values), so this constructor runs exactly when stealing is allowed.

The recipe for a class that owns a raw resource:

  1. Copy the pointer (and sizes) from other into the new object.
  2. Set other's pointer to nullptr (and sizes to 0), so its destructor won't free what you just took.
#include <cstring>
#include <iostream>
#include <utility>

class Text {
public:
    explicit Text(const char* s) : len_(std::strlen(s)), buf_(new char[len_ + 1]) {
        std::memcpy(buf_, s, len_ + 1);
    }
    ~Text() { delete[] buf_; }
    Text(const Text&) = delete;
    Text& operator=(const Text&) = delete;

    Text(Text&& other) noexcept : len_(other.len_), buf_(other.buf_) {
        other.buf_ = nullptr;          // other no longer owns the buffer
        other.len_ = 0;
        std::cout << "moved\n";
    }

    const char* c_str() const { return buf_ ? buf_ : "(empty)"; }

private:
    std::size_t len_;
    char* buf_;
};

int main() {
    Text a("hello");
    Text b(std::move(a));              // runs the move constructor
    std::cout << b.c_str() << " / " << a.c_str() << "\n";
}                                      // both destructors run; delete[] nullptr is harmless
moved
hello / (empty)

Why each part matters

Your turn: write the move constructor for Buffer.

Previous: Copies are expensive Next: Move assignment and the rule of five