在类的operator= 中处理自我赋值的情况。
在说这个主题之前,先考虑一下代码:
class string
{
public:
string& operator=(const string& rhs)
{
delete pstr;
strcpy(pstr,rhs.pstr);
return *this;
}
private:
char* pstr;
}
显然这一段代码中如果this 与rhs指向的是同一个对象,程序就会出现不明确的行为。
解决自我赋值问题主要有三大方法:
1.判断是否是同一个对象。
2.在删除自身资源前保留一份副本。
3.copy and swap技术
现在分别以三段代码来展示这三个技术:
判断是否是同一个对象:
class string
{
public:
string& operator=(const string& rhs)
{
if(*this==rhs)
return *this;
delete pstr;
strcpy(pstr,rhs.pstr);
return *this;
}
private:
char* pstr;
}
这种判断是否是同一个副本的代码,在某些情况下可能不是异常安全的,。
在删除自身资源前保留副本:
class string
{
public:
string& operator=(const string& rhs)
{
char* pstrold=pstr;
pstr=new char[strlen(rhs.pstr)+1];
delete pstrold;
return *this;
}
private:
char* pstr;
}
这种做法是异常安全的代码,在new char 抛出异常的时候,原来的pstr信息并没有丢失。
copy and swap的做法
class string
{
public:
void swap(string& rhs){ ...}
string& operator=(const string& rhs)
{
string tmp(rhs);
swap(tmp);
return *this;
}
private:
char* pstr;
}
这也是一种异常安全并且能解决自我赋值的方案