当我们编写赋值运算符时,有两点需要记住:
- 如果将一个对象赋予它自身,赋值运算符必须能正确工作;
- 大多数赋值运算符组合了析构函数和拷贝构造函数的工作。
当我们编写一个赋值运算符时,一个好的模式是先将右侧运算对象拷贝到一个局部临时对象中。当拷贝完成后,销毁左侧运算对象的现有成员就是安全的了。一旦左侧运算对象的资源被销毁,就只剩下将数据从临时对象拷贝到左侧运算对象的成员中了。
class HasPtr
{
public:
HasPtr(const std::string &s = std::string()) : ps(new std::string(s)), i(0){}
HasPtr(const HasPtr &p) : ps(new std::string(*p.ps)), i(p.i) {}
~HasPtr() { delete ps; }
HasPtr& operator=(const HasPtr&p);
private:
std::string *ps;
int i;
};
HasPtr& operator=(const HasPtr&p); 的实现:
HasPtr &HasPtr::operator=(const HasPtr &p)
{
auto tmp = new std::string(*p.ps);
delete ps; // 释放旧内存
ps = tmp;
i = p.i;
return *this;
}
网友评论