赋值运算符'='重载
·赋值运算符两边的类型可以不匹配
·把一个int类型变量赋值给一个complex对象
·把一个char*类型的字符串赋值给一个字符串对象
·需要重载赋值运算符'='
·赋值运算符'='只能重载为成员函数
·编写一个长度可变的字符串类String
·包含一个char*类型的成员变量---指向动态分配的存储空间
·该存储空间用于存放'\0'结尾的字符串
class String{
private:
char* str;
public:
String():str(NULL){}//构造函数,初始化str为NULL
const char* c_str(){//返回str指针,不希望在外部能够通过利用str这个指针去修改这个指针所指向那块内存空间的内容,所以设置为const类型
return str;
}
char* operator = (const char* s);
~String();
};
//char* p = s.c_str();//就会报错
//重载'='---obj = "hello"能够成立
char* String::operator = (const char* s){
if(str)//判断当前obj所对应的内存空间是否为空
delete []str;
if(s){//s不为NULL才会执行拷贝
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";//s.operator=(" ");
cout << s.c_str() << endl;
//String s2 = "hello!"; //初试化语句不会调用,只会调用String(char*)构造函数,这条语句要是不注释就会出错
s = "Shenzhou 8!"
cout << s.c_str() << endl;
return 0;
}
程序输出结果:
Good Luck
Shenzhou 8!
重载赋值运算符的意义--浅复制和深复制
·S1 = S2
·浅复制/浅拷贝
·执行逐个字节的复制工作
String S1, S2;
S1 = "this";
S2 = "that";
S1 = S2;
String S1, S2;
S1 = "this";
S2 = "that";
s1 str ------- t h i s \0
s2 str ------- t h a t \0
S1 = S2;
s1 str/s2 str(同时) ------- t h a t \0
原先的内存空间没有任何指针控制,成为了内存垃圾;当s1和s2同时消亡时,另一个内存空间就会被释放两次,会导致严重的内存错误,引发程序的以外终止
·深复制/深拷贝
·将一个对象中指针变量指向的内容---复制到另一个对象中指针成员对象指向的地方
String S1, S2;
S1 = "this";
S2 = "that";
S1 = S2;
String S1, S2;
S1 = "this";
S2 = "that";
s1 str ------- t h i s \0
s2 str ------- t h a t \0
S1 = S2;
s1 str ------- t h a t \0
s2 str ------- t h a t \0(各自)
实现深复制
·在class String里添加成员函数
String & operator = (const String &s){
if(str)
delete []str;
str = new char[strlen(s.str) + 1];
strcpy(str, s.str);
return *this;
}
·思考下面语句
MyString s;
s = "hello";
s = s;
是否会有问题?
正确写法:
String & 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 &
·运算符重载时,好的风格--尽量保留运算符原本的特性
考虑:(a = b) = c;//会修改a的值
·分别等价于:
(a.operator = (b)).operator = (c)
上面的String类是否就没有问题了?
·为String类编写复制构造函数时
·会面临和'='同样的问题,用同样的方法处理
String::String(String &s){
if(s.str){
str = new char[strlen(s.str) + 1];
strcpy(str, s.str);
}
else
str = NULL;
}