赋值运算符只能重载为成员函数
class String
{
private:
char * str;
public:
String():str(NULL){} //构造函数,初始化成员列表初始化为NULL
const char * c_str() { return str; }
char* operator= (const char* s);
~String();
};
char * String::operator=(const char * s) //使得obj = "hello"可以执行
{
if(str) delete[] str;
if(s)
{
str = new char[strlen(s)+1];
strcpy(str, s);
}
else str=NULL;
return str;
}
String::~String()
{
if(str) delete []str;
}
int main()
{
String s;
s="Good luck";
cout<<s.c_str()<<endl;
// String s2="hello"; //这条语句不注释会出错
return 0;
}
重载赋值运算符的意义——深复制和浅复制
浅复制会造成:(1)s1原来指向的内存空间成为内存垃圾;(2)s1和s2指向同样的内存地址,当s1和s2消亡时,该地址会被释放两次,造成严重的内存错误;
深复制:将一个对象中指针变量指向的内容,复制到另个对象中指针成员对象指向的地方。
// 在类class String中添加成员函数
String & operator= (const String& s)
{
if(str) delete [] str;
str = new char[strlen(s.str)+1];
strcpy(str, s.str);
return *this;
}
上述代码中,考虑下面语句:
String s;
s="Hello";
s=s; //会出现错误,赋值运算符开始就将s的str 释放掉;
正确写法应为:
String & operator= (const String& s)
{
if(str == s.str) return *this;
if(str) delete [] str;
if(s.str)
{
str = new char[strlen(s.str)+1];
strcpy(str, s.str);
}
else str = NULL:
return *this;
}
思考:operator =返回值类型的讨论,返回值为void可以吗?考虑:a = b = c;
//等价于 a.operator = (b.operator=(c));将不可行
编写类的复制构造函数同样需要考虑上述问题:
String(String &s)
{
if(s.str)
{
str = new char[strlen(s.str)+1];
strcpy(str, s.str);
}
else str = NULL;
}