交换操作
除了定义拷贝控制成员,管理资源的类通常还定义一个swap函数。对于和重排元素顺序的算法一起使用的类,定义swap非常重要。
如果一个类未定义swap则算法将使用标准库定义的版本。
交换值的swap需要临时变量:
T temp = v1;
v1 = v2;
v2 = temp;
交换指针的则不必浪费临时变量的内存分配,以HasPtr为例:
string* temp = v1.ps;
v1.ps = v2.ps;
v2.ps = v1.ps;
可以编写类外的swap,将其定义为类的友元以访问private的数据成员。
由于swap就是为了优化代码,可以将其声明为inline函数。
swap函数应该调用swap,而不是std::swap
即使使用了using std::swap,在定义了swap的作用域中该自定义的swap的匹配优先级依然高于std::swap。
在赋值运算符中使用swap
定义了swap的类通常使用swap定义他们的赋值运算符。这些运算符使用了一种名为 拷贝并交换(copy and swap) 的技术,将lhs与rhs运算对象的一个副本进行交换,因此该版本的赋值运算符参数并非引用而是传值。
HasPtr& HasPtr::operator=(HasPtr rhs){
swap(*this, rhs);
return *this;
}
离开作用域后,rhs指向的新的位置会被析构进而销毁。
该技术自动处理了自赋值情况,且天然具有安全性。代码中唯一可能抛出异常的是拷贝构造函数中的new表达式。