注意点
返回值类型为该类型的引用,并且在函数结束时返回实例自身的引用(*this)
只有返回一个引用才允许连续赋值(链式访问)
参数的类型声明为常量引用
1.如果传入的参数不是引用而是实例,那么从形参到实参会调用拷贝构造函数,降低代码效率。(传引用不需调用拷贝构造函数)
2.在函数体内不会改变传入的实例(引用前加const)释放实例自身已有的内存(防止内存泄漏)
判断传入参数与当前实例是否为同一个实例
当传入的参数与*this是同一个实例,一旦释放自身的内存,参数的内存将一同释放,将找不到需要赋值的内容
class Mystring
{
public:
Mystring()
:p_data(0)
{}
Mystring(const Mystring& str)
{
p_data = str.p_data;
}
Mystring& operator = (const Mystring & s);
~Mystring(void)
{
if (NULL == p_data)
{
delete[] p_data;
p_data = NULL;
}
}
private:
char* p_data;
};
LOW
Mystring& Mystring::operator = (const Mystring & s)
{
if (this == &s)//判断参数和当前实例是不是相同
return *this;
delete[] p_data;//释放实例
p_data = NULL;//置空
p_data = new char[strlen(s.p_data) + 1];//重新开辟空间
strcpy(p_data,s.p_data);//将参数数据拷贝到当前实例数据
return *this;
}
GOOD
Mystring& Mystring::operator = (const Mystring & s)
{
if (this != &s)//判断参数和当前实例是不是相同
{
Mystring pTmp(s);创建一个临时实例
char *tmp = pTmp.p_data;
pTmp.p_data = p_data;
p_data = tmp;
}
return *this;
}
//临时变量除了作用域将自动调用析构函数进内存释放