copy-and-swap是为了赋值操作符和move构造器能够更优雅(而且稳定)地完成工作而出现的。Rule Of Three要求自己定义的类如果提供了以下其中之一,就要提供全部:
- 析构器
- 复制构造器
- 复制赋值操作符
C++11就成了Rule Of Five:
- 复制构造器
- 复制赋值操作符
- 析构器
- 移动构造器
- 移动赋值操作符
废话不多说,直接写比较成熟的方案,来自于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只应该控制一个资源,多个资源会带来混乱和麻烦。