Post

C++ - Copy-and-swap Idiom

C++ - Copy-and-swap Idiom

I faced an issue implementing BusTub P1 correctly. It’s all about move semantic and resource ownership. I found the “copy-and-swap idiom” very helpful in solving this problem. Here’s a brief explanation of the idiom and how it can be applied in C++.

Motivation

Resource management challenges

When implementing copy/move constructors and assignment operators, we often need to release allocated resources. But this is easy to forget, leading to resource leaks or double frees.

Exception safety

swap(x, y) is usually implemented noexcept, so it won’t throw exceptions. This property helps ensure that our assignment operators are not leading to resource leaks.

Mechanism

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Widget {
  public:
   // You should implement these two as usual.
    Widget(Widget const& other);
    Widget(Widget&& other) noexcept;

    Widget& operator=(Widget other) noexcept {   // note: pass by value
        if (this != &other) swap(*this, other);  // swap the contents
        return *this;
    }

  private:
    friend void swap(Widget& first, Widget& second) noexcept {
        using std::swap;
        // swap all members here, e.g.:
        // swap(first.member1, second.member1);
        // swap(first.member2, second.member2);
    }
};

Don’t use operator=(Widget&& other). In this way, destruction of original resource will be deferred to destruction of outer other, which may not be what you want.

If you want the resource to be cleaned just in time, or you want to disable one of copy and/or move, using seperated implementation for copy/move assignment, you can try the following:

1
2
3
4
5
6
7
8
Widget& operator=(Widget &&other) noexcept { // note: passed by r-value reference.
    // When implementing the `Widget const&` version, use `auto tmp = other;`.
    if (this != &other) {
        auto tmp = std::move(other);
        swap(*this, tmp);  // swap the contents
    }
    return *this;
}
This post is licensed under CC BY 4.0 by the author.