CString& CString::operator=(const CString& str){
if(this == &str) //1.自赋值检查
return *this;
if(pChar!=NULL) //2.释放原有空间
delete[] pCahr;
pChar = new char[strlen(str.pChar)+1]; //
2.申请新空间
strcpy(pChar, str.pChar); //2.数据复制 (不要忘记对基类的赋值)
return *this; //3.返回对象的引用
}
█不要让编译器帮你重载赋值运算符(浅拷贝、POD对象、堆内存)
█一定要检查自赋值
1)效率,特别是具有内存分配操作。
2)如果目标对象pChar不为NULL,会将目标对象pChar指向的内存首先释放。又因为自赋值,原对象pChar与目标对象pChar指向通过目标对象 pChar 释放掉的空内存空间。后续操作的危险性不言而喻。
【自赋值操作】
█赋值运算符重载需返回 *this 的应用(链式赋值【内置数据类型支持】)
例如:
class CString{ };
CString str1("Hello C++");
CString str2, str3;
str3 = str2 =str1;
相当于:str3.operator=(str2.operator=(str1));//赋值运算符具有右结合性
返回值应为“引用”:
1)效率(避免返回对象构造、析构的过程)
2)存在括号改变赋值的顺序:
class CString{ };
CString str1("Hello C++");
CString str2, str3;
(str3 = str2) =str1; //如果非引用,将返回临时对象,临时对象不允许调用成员函数
█赋值运算符重载函数不能重载 //虽然没有显式地为派生类声明赋值运算符重载函数,但是不要忘记编译器悄悄做的事!基类 operator= 被隐藏。
█派生类中 operator= 重载函数应为对象中的所有数据成员进行一一赋值,最重要的是:基类部分(最简单的方式,即直接调用基类的
operator= )。
编写高质量代码——重载operator=的标准三步走