赋值运算符重载

赋值运算符'='重载
·赋值运算符两边的类型可以不匹配
    ·把一个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;
}

 

你可能感兴趣的:(C++学习)