原创 中国大学MOOC程序设计与算法(三):C++ 面向对象程序设计 第四周 运算符重载 笔记 之 赋值运算符的重载

标签: 程序设计  c++    面向对象编程

第四周 运算符重载
1.运算符重载的基本概念
2.赋值运算符的重载
3.运算符重载为友元函数
4.运算符重载实例:可变长数组类的实现
5.流插入运算符和流提取运算符的重载
6.类型转换运算符、自增自减运算符的重载

2.赋值运算符的重载

有时候希望赋值运算符两边的类型可以不匹配,比如,把一个int类型变量赋值给一个Complex对象,或把一个 char * 类型的字符串赋值给一个字符串对象,此时就需要重载赋值运算符“=”。

赋值运算符“=”只能重载为成员函数

例子:

class String {
	private:
		char * str;
	public:
		String ():str(new char[1]) { str[0] = 0;}
		const char * c_str() { return str; };
		String & operator = (const char * s);
		String::~String( ) { delete [] str; }
};
String & String::operator = (const char * s)
{ 
	// 重载“=”得 以使得 obj = “hello” 能够成立
	delete [] str;
	str = new char[strlen(s)+1];
	strcpy( str, s);
	return * this;
}
int main()
{
	String s;
	s = "Good Luck," ; //于 等价于 s.operator=("Good Luck,");
	cout << s.c_str() << endl;
	// String s2 = "hello!"; // 这条语句要是不注释掉就会出错,因为这里不是赋值语句而是初始化语句,调用的不是重载的赋值符号而是构造函数,这里没有定义相应的构造函数
	s = "Shenzhou 8!"; //于 等价于 s.operator=("Shenzhou 8!");
	cout << s.c_str() << endl;
	return 0;
}
输出:
Good Luck,
Shenzhou 8!

浅拷贝和深拷贝

class String {
	private:
		char * str;
	public:
		String ():str(new char[1]) { str[0] = 0;}
		const char * c_str() { return str; };
		String & operator = (const char * s){
			delete [] str;
			str = new char[strlen(s)+1];
			strcpy( str, s);
			return * this;
		};
		~String( ) { delete [] str; }
};

String S1, S2;
S1 =this;
S2 = “that”;
S1 = S2;

如果不定义自己的赋值运算符:
结果是那么S1=S2实际上导致 S1.str和 S2.str指向同一地方。
在这里插入图片描述
这会产生以下几个后果
1) S1.str原来指向的地方被废弃,永远不会再被释放,成为内存垃圾;
2) 如果S1对象消亡,析构函数将释放 S1.str指向的空间,则S2消亡时还要释放一次,不妥,因为new出来的空间只能delete一次,程序崩溃。
3) 另外,如果执行 S1 = “other”;会导致S2.str指向的地方被delete。
因此要在 class String里添加成员函数:

String & operator = (const String & s) {
	delete [] str;
	str = new char[strlen( s.str)+1];
	strcpy( str,s.str);
	return * this;
}

这么做就够了吗?还有什么需要改进的地方?考虑下面语句:

String s;
s = "Hello";
s = s;//用自己赋值自己

问题:自己的内存已经先被释放了,然后访问就回出错
解决办法:

String & operator = (const String & s){
	if( this == & s)
		return * this;
	delete [] str;
	str = new char[strlen(s.str)+1];
	strcpy( str,s.str);
	return * this;
}

对 operator = 返回值类型的讨论
void 好不好?
String 好不好?
为什么是 String &
对运算符进行重载的时候,好的风格是应该尽量保留运算符原本的特性
考虑: a = b = c;和 (a=b)=c; //会修改a的值
分别等价于:

a.operator=(b.operator=(c));
(a.operator=(b)).operator=(c);//(a=b)返回a的引用

上面的String类是否就没有问题了?
为 String类编写复制构造函数的时候,会面临和 = 同样的问题,用同样的方法处理。避免指向同一个空间

String( String & s)
{
	str = new char[strlen(s.str)+1];
	strcpy(str,s.str);
}
版权声明:本文为weixin_41919587原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_41919587/article/details/103657449

智能推荐

更改springboot启动拼成的字母

1.更改springboot启动拼成的字母 其实很好改,只需要在resources下新建一个txt文件就可以,命名为banner.txt,那这种字符该怎么拼出来呢,下面推荐一个网址,有这种工具 传送门 2.集成...

Node.js安装配置

好久都没更新博客了,今天心血来潮,决定是时候更新一篇了,首先我们来认识一下node.js。 什么是node.js? 简单的说 Node.js 就是运行在服务端的 JavaScript。 Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台。 Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行Javascript的...

RocketMQ之双Master集群搭建笔记记录

一:RocketMQ双master集群部署 服务器环境(我采用的虚拟机,centos6 .5【特别注意:安装的虚拟机centos系统一定得是64位的,32位的会启动不起来。即便起来了也会有很多问题,深坑勿踩】)  ip       用户名    密码        角色     模式 192.168.197.101   root        nameServer1,brokerServer1  ...

蓝桥杯试题集-基础练习题-数列特征(Java)

//做题笔记,仅自己看得懂 题目: 正确姿势:...

多线程爬取4k超高清美图壁纸

多线程爬取4k美图壁纸 前言:看完此篇文章你可以更加深入的了解多线程的使用,并且最重要的你能够下载你自己想要的超高清4k壁纸 爬取结果: 1. 分析网站 要爬取的url :http://pic.netbian.com/ a) 判断网页是动态加载还是静态加载页面。右击查看网页源代码,按Ctrl + f在源代码中搜索网站的详情页地址,从而判断整个网页是静态加载的 b) 明确爬取的目标。我们要爬取的目标...

猜你喜欢

elementUI-添加自定义图标

elementui的小图标有限,跟UI给的不一样,这个时候咋办呢?百度走起。。。。参考了两篇博主分享的 自定义elementui中的图标 和 建立图标库,这里主要用到第一种 实际中: elementUI导航栏 具体代码: 汉字转换Unicode编码: 直接打开控制台: 汉字.chatCodeAt().toString(16); 然后回车; 至于三角形的图标,我直接把箭头的 unicode 值改成了...

[Linux]——文件缓冲区

文件缓冲区 提到文件缓冲区这个概念我们好像并不陌生,但是我们对于这个概念好像又是模糊的存在脑海中,之间我们在介绍c语言文件操作已经简单的提过这个概念,今天我们不妨深入理解什么是文件缓冲区。 为什么需要文件缓冲区 当我们在程序中写下一条printf语句时,我们希望将这条语句的内容打印到屏幕上。但是如果你将语句放在循环中,难道你执行一次循环那么操作系统就要打印一次这条数据么?答案当然不是 我们对于程序...

基于FPGA的IIC协议详解——EEPROM控制器(1)

IIC协议举例 常用IIC协议使用地方 常见IIC协议的注意点 24LC64芯片读写命令的时序图 eeprom控制器的系统框图 时序图设计 代码设计 EEPROM控制器测试模块的代码 结束语 常用IIC协议使用地方 熟悉一个协议一定要知道这个协议应该用到什么地方,IIC协议作为飞利浦公司定义的一个慢速传输协议,常用于: 1、芯片寄存器的配置; 2、eeprom的读写; 本次实验我们将使用eepro...

ssm 工程简易搭建(idea 工具下)

现在都流行springboot了,大部分都给你配合了了,可以快速开发。但是今天我们回顾一下ssm的搭建,其实也挺简单的,比刚入门那会觉得简单多了。 这个先讲几点: 1.开始搭建前,idea 自己要配置maven 和tomcat和jdk ,这里就不讲了。 2.为了简化配置,我们按照“约定优于配置”的原则(这种原则在sprigboot项目里面特别明显),启动项目时,项目有个文件...

oracle简单视图read only、check option和默认权限的异同(相对于DML语句)

视图分为俩类: 简单视图:   视图所代表的sql中如果没有group by语句,   没有组函数,查询的只有一张表,那么这样的视图就是简单视图. 复杂视图   视图所代表的sql中如果有group by语句,   或者有组函数,或者查询的是多张表,那么这样的视图就是复杂视图. s_emp表格属性 默认权限 1.可以插入不满足where条件的数据,原表也会更...