重载操作符,遵循的规则是 A& operator =(const A& rhs);在重载=时,1、要考虑证同情况即自我赋值,即A a; a=a;
2、考虑异常安全的情况,避免内存分配失败,例如:
A& operator =(const A& rhs)
{
if(this == &rhs) return this;//证同
delete pb;//pb是A中的一个成员变量BitMap*,BitMap是一个类
pb = new BitMap(*rhs.pb);//*rhs.pb表示pb所指向的数据
return *this;
}
如果new 失败,抛出异常,则返回的A的引用中成员变量pb将指向一个已经被删除的内存,这就导致异常出现的不安全.
解决办法一:只需要注意在复制pb所指的东西之前别删除pb,如下:
A& operator =(const A& rhs)
{
BitMap *porg = pb;//记住原先的pb
pb = new BitMap(*rhs.pb);//令pb指向*pb的一个副本
delete porg ;//删除原先的pb
return *this;
}
这样,如果new异常,pb仍保持原状,这仍然能进行自我赋值,因为new BitMap(*rhs.pb)就是将自己的数据进行了一份拷贝,然后再赋值给自己。只是不是太高效。
解决办法二:
A& operator =(const A& rhs)
{
if(this != &rhs) //证同
{
A temp(rhs);
BitMap *ptemp = temp.pb;
temp.pb = pb;
pb = ptemp ;
}
return *this;
}
先创建一个临时实例,接着让实例中的成员变量pb和自身的pb进行交换,这样就没有删除pb,只是把pb的地址改了。而临时实例只要出了if就会自动调用析构函数,把实例所指向的原来的内存给释放了。所以这个方法最高效.如果在创建临时实例的时候,new失败,则我们还没有修改原来的实例状态,就退出。这样实例的状态还是有效的,就保证了异常安全。