1. 类对象的交换赋值
Hasptr.h
class Hasptr
{
public:
Hasptr(const std::string &s = std::string()):
ps(new std::string(s),
i(0),
use(new std::size_t(1))) {
}
Hasptr(const Hasptr &p):ps(p.ps),i(p.i),use(p.use){
++*use};
Hasptr& operator=(const Hasptr&);
~Hasptr();
private:
std::string *ps;
int i;
std::size_t *use;
}
交换代码为:
Hasptr temp = v1; //创建v1的一个临时副本
v1 = v2; //将v2赋值给v1
v2 =temp; //将保存v1的值赋予v2
2. 优化
在上面的交换过程中,需要一次拷贝和两次赋值,string的内存分配带来了开销, 更希望 swap 交换指针,而不是分配 string 的新副本:
string &temp = v1.ps;
v1.ps = v2.ps;
v2.ps = temp.ps;
2. 1 可以在类上自定义一个版本的 swap,当交换两个HasPtr对象时,只需要交换他们内部的指针即可:
class HasPtr{
friend void swap(HasPtr &lhs,HasPtr &rhs);
}
inline swap(HasPtr&,HasPtr&)
{
using std::swap;
swap(lhs.ps,rhs.ps); //交换指针,而不是string的数据
swap(lhs.i;rhs.i); //交换int成员
}
2. 2 赋值运算符中使用 swap
使用拷贝并交换的技术,这种技术将左侧运算对象与右侧运算对象的一个副本进行交换。
rhs 是按值传递的:
HasPtr& HasPtr::operator=(HasPtr rhs)
{
//交换左侧运算对象和局部变量rhs的内容
swap(*this,rhs);
return *this; //rhs 被销毁,从而delete了rhs中的指针
}
- 注:赋值运算符具备异常安全、且能正确处理自赋值。
【参考】
[1] 代码referenceCountSwap.h