From:http://topic.csdn.net/t/20040830/15/3322731.html
为什么在重载operator=时需要检测自赋值情况呢?
书上说是不检测的话很危险,能不能举例子说明??
Paris_Luo的意思是这样:
String::operator=(const String& src)
{
//不检查自赋值,一般代码如下,先释放,后拷贝
delete[] data;
data = new char[strlen(str.data) + 1];//Paris_Luo少写了这一句
memcpy(data,src,strlen(str.data)+1); //自赋值时,拷贝一块已释放的内存!!
return *this;
}
在自赋值发生的时候,代码中的data和str.data其实是同一个,那么在第二句中就访问了在第一句中已经释放了的内存(strlen(str.data),str.data已经释放),这种操作是很危险的。
不过即使没有自赋值的问题,这段代码也有问题:
在data = new char...时是可能产生异常的,然后对象中的data将指向一段没有释放的内存,这个对象已经不能正常工作,甚至不能正常析构。如果在delete[]data之后加一句data = NULL虽然可以解决这个问题,但仍然不好——这样只是保证了对象能使用而没有保证对象状态,一个好的赋值操作符应该在产生异常时保持对象状态与未赋值前一样。正确的实现应该是:
String::operator=(const String& src)
{
char * newdata = NULL;
if (str.data != NULL)
{
newdata = new char[strlen(str.data) + 1];
strcpy(newdata, str.data);
}
delete[] data;
data = newdata;
return *this;
}
这个实现大家可以看到:即使自赋值发生了,仍然不会有问题,只不过做了一些不必要的操作罢了。所以Pari_Luo这个例子并不能说明问题,它在解决了异常安全问题之后就不存在自赋值问题了。