赋值运算符重载

本文详细介绍了C++中自定义字符串类的实现方法,并深入探讨了赋值运算符重载的原理及其重要性。通过具体实例展示了如何避免浅复制导致的问题,确保深复制的正确实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值