C++|copy-and-swap idiom

于 2020-06-23 发布

copy-and-swap是为了赋值操作符和move构造器能够更优雅(而且稳定)地完成工作而出现的。Rule Of Three要求自己定义的类如果提供了以下其中之一,就要提供全部:

  1. 析构器
  2. 复制构造器
  3. 复制赋值操作符

C++11就成了Rule Of Five

  1. 复制构造器
  2. 复制赋值操作符
  3. 析构器
  4. 移动构造器
  5. 移动赋值操作符

废话不多说,直接写比较成熟的方案,来自于Stack Overflow

1
2
3
4
5
6
7
8
9
10
11
class AClass{
int length_;
int * array;
public:
...
    friend void swap(AClass & dest, AClass& src) noexcept {
        using std::swap;
        swap(dest.length_, src.length_);
        swap(dest.array, src.array);
    }
};

核心就是这个swap方法,用到了ADL——为了满足ADL所以要写成friend,更深入的原因看这个

有了swap之后,就可以把移动构造器写成这样:

1
2
3
AClass::AClass(AClass&& another) noexcept : AClass() {
    swap(*this,another);
}

需要调用默认构造器来先把this给设置好,再swap。

然后把赋值构造器统一成:

1
2
3
4
AClass& operator=(AClass another){
    swap(*this,another);
    return *this;
};

所以Rule of Five就会变成Rule of Four and A Half.

这种方法对于只控制一个资源的class很有效,但是习惯上,一个class只应该控制一个资源,多个资源会带来混乱和麻烦。

目录