赋值运算符重载:
赋值运算符重载需要考虑什么问题:
Class mystring
{
Public:
Mystring(char*pdata = NULL);
Mystring(constmystring& str);
~mystring(void);
Private:
Char* m_pdata;
};
在重载时候需要考虑的问题:
1、 是否把返回值的类型声明为该类型的引用,并在函数结束前返回实例自身(*this)的引用?只有返回一个应用,才可以允许连续赋值。
2、 是否把传入的参数的类型声明为常量引用?如果传入的参数不是引用而是实例,那么从形参到实参会调用一次拷贝构造函数。把参数申明为引用可以避免。
3、 是否需要释放实例自身有的内存?
4、 是否判读传入的参数是不是和当前的实例(*this)是不是同一个实例?如果是同一个直接返回。
Mystring & Mystring::operator=(constmystring& str)
{
if(this ==&str)
return*this;
delete []pdata;
pdata = new char[strlen(str)+1];
strcpy(pdata,str.pdata);
return*this;
}
继续来看上面的这段代码,显示地用delete释放自身pdata的内存,同时我们也会在析构函数中调用释放自身pdata的内存,如果使用这个类型中添加新的指针成员变量,那么我们至少需要做两处修改,既同时在析构函数和这个赋值运算符里添加一条delete语句来释放新指针所指向的内存,一个改动需要在代码中多个地方修改代码,通常是不安全的。通常我们会记得在析构函数中调用delete释放指针成员变量,但务必每次都记得到赋值运算符来添加代码释放内存。
更好的方法在复制运算符函数中利用析构函数自动释放实例已有的内存。
Mystring& mystring::operator=(const mystring& str)
{
If(this !=&str)
{
Mystringstrtemp(str); //弄一个临时变量 但是使用的函数是应定义好的拷贝构造函数,这个时候strtemp是一个新的对象,而且是完整的
Char*temp_pdata = strtemp.pdata;
Strtemp.pdata= pdata;
Pdata =temp_pdata;
}
Return*this
}
上面if判断内的操作相当于,将拷贝构造函数和原来的内存指针之间相互替换,然后利用strtemp的作用域使得在if之外就可以自动调用strtemp的析构函数