【C++从0到王者】第二站:类和对象(中)赋值运算符重载

news2025/1/24 7:16:59

文章目录

  • 一、运算符重载
    • 1.运算符重载的使用
    • 2.运算符重载的注意事项
  • 二、赋值运算符重载
    • 1.复制拷贝与拷贝构造
    • 2.赋值运算符重载的格式
    • 3.赋值运算符重载的实现
    • 4.赋值运算符重载的注意事项

一、运算符重载

1.运算符重载的使用

当我们实现一个日期类的时候,我们有时候需要比较两个类的大小。我们可以写一个普通的函数去进行比较,但是这样比较繁琐,我们能否像内置类型那样只需要使用比较符号来进行判断呢?其实是可以的,C++为什么支持内置类型的比较呢?这是因为内置类型的都是祖师爷知道的,祖师爷知道他们如何进行比较,所以将内置类型的比较方法早已写入库中,而自定义类型祖师爷是不知道的,所以需要我们自己来实现,我们在实现的时候为了可以使用普通的比较符号,我们可以使用运算符重载

class Date
{
public:
	Date(int year = 2023, int month = 5, int day = 10)
	{
		_year = year;
		_month = month;
		_day = day;
	}

//private:
	int _year;
	int _month;
	int _day;

};
bool operator<(const Date& x1, const Date& x2)
{
	if (x1._year < x2._year)
	{
		return true;
	}
	else if (x1._year == x2._year && x1._month < x2._month)
	{
		return true;
	}
	else if (x1._year == x2._year && x1._month == x2._month && x1._day < x2._day)
	{
		return true;
	}
	return false;
}
int main()
{
	Date d1(2023, 5, 11);
	Date d2(2023, 5, 12);
	cout << (d1 < d2) << endl;
	cout << operator<(d1, d2) << endl;
	cout << (d2 < d1) << endl;
	cout << operator<(d2, d1) << endl;
	return 0;
}

像上面代码中的d1<d2事实上就被转化为了operator<(d1,d2),我们可以从指令的角度来进行观察:可以发现其实是一样的
在这里插入图片描述

但是上面的代码仍然不够完善,因为他是定义在类外的,必须将私有成员变量给变为公有的,如果想要使用私有的,有两种方案:1.使用友元,但是这样会破坏封装,2.直接定义在类内,这样的话我们需要注意一点的是,在内里的变量是有一个this指针的,所以我们的形参数其实是需要少一个的

	bool operator<(const Date& x)
	{
		if (_year < x._year)
		{
			return true;
		}
		else if (_year == x._year && _month < x._month)
		{
			return true;
		}
		else if (_year == x._year && _month == x._month && _day < x._day)
		{
			return true;
		}
		return false;
	}

这时候他就是这样的等价了
在这里插入图片描述

2.运算符重载的注意事项

C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数,也具有其返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。
函数名字为:关键字operator后面接需要重载的运算符符号。
函数原型:返回值类型 operator操作符(参数列表)

  1. 不能通过连接其他符号来创建新的操作符:比如operator@
  2. 重载操作符必须有一个类类型参数
  3. 用于内置类型的运算符,其含义不能改变,例如:内置的整型+,不 能改变其含义
  4. 作为类成员函数重载时,其形参看起来比操作数数目少1,因为成员函数的第一个参数为隐藏的this
  5. .* :: sizeof ?: . 注意以上5个运算符不能重载
  6. 操作符是几个操作数,重载运算符函数就有几个参数

二、赋值运算符重载

1.复制拷贝与拷贝构造

首先我们需要搞清楚复制拷贝与拷贝构造的区别:

  • 拷贝构造是使用一个已经存在的对象去初始化另外一个对象
  • 复制拷贝是已经存在的两个对象进行的复制拷贝
    在这里插入图片描述

2.赋值运算符重载的格式

  • 参数类型:const T&,传递引用可以提高传参效率
  • 返回值类型:T&,返回引用可以提高返回的效率,有返回值目的是为了支持连续赋值
  • 检测是否自己给自己赋值
  • 返回*this :要复合连续赋值的含义

3.赋值运算符重载的实现

	Date operator=(const Date& x)
	{
		_year = x._year;
		_month = x._month;
		_day = x._day;
		return *this;
	}

如上是复制运算符重载的实现,这里我们需要注意的是,我们需要传一个返回值,这是为了满足连续赋值的场景。
但是还需要注意的是,我们这里的是传值返回,传值返回的过程会产生一个临时变量,这个临时变量就会调用拷贝构造函数去构造这个临时变量。然后在将临时变量的数据交给变量
在这里插入图片描述在这里插入图片描述在这里插入图片描述

但是这样的话代价太大了,因为需要调用拷贝构造,我们注意到*this出了这个赋值运算符重载函数还在,所以我们可以使用传引用返回,这样就减少了拷贝构造的代价了

	Date& operator=(const Date& x)
	{
		cout << "Date operator=(const Date& x)" << endl;
		_year = x._year;
		_month = x._month;
		_day = x._day;
		return *this;
	}

在这里插入图片描述有时候,为了防止我们写出的d1=d1这样的代码,我们可以进行这样的优化

	Date& operator=(const Date& x)
	{
		cout << "Date operator=(const Date& x)" << endl;
		if (this != &x)
		{
			_year = x._year;
			_month = x._month;
			_day = x._day;
		}
		return *this;
	}

或许可能会认为这里有点作用,但不大,只是起了优化的作用而已,其实不是这样的,这是因为日期类只涉及到浅拷贝,如果涉及到深拷贝的话,就会出现内存泄漏了。所以是非常有必要这样写的

4.赋值运算符重载的注意事项

  1. 赋值运算符只能重载成类的成员函数不能重载成全局函数

因为他是默认成员函数,自己在类中不写,编译器会自己生成,就会产生冲突

  1. 用户没有显式实现时,编译器会生成一个默认赋值运算符重载,以值的方式逐字节拷贝。注意:内置类型成员变量是直接赋值的,而自定义类型成员变量需要调用对应类的赋值运算符重载完成赋值

默认生成的赋值运算符重载与拷贝构造的行为一样:

  • 内置类型成员 --值拷贝/浅拷贝
  • 自定义类型成员调用它的赋值重载

所以我们就可以看出来,Date类和MyQueue类是不需要自己写赋值重载的,而Stack是需要写的,因为默认生成的是浅拷贝


本节内容就到这里了,如果对你有帮助的话,不要忘记点赞加收藏哦!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/521665.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Angular开发之——Angular打包部署项目(04)

一 概述 ng build 构建应用lite-server介绍及安装lite-server部署应用IIS管理器部署应用 二 ng build 构建应用 2.1 执行如下指令构建应用 ng build2.2 构建完成后&#xff0c;会创建一个 dist 文件夹 2.3 直接打开index.html会出错(需要借助于服务器部署) 三 lite-server介…

(二)PUN 2基本教程

一、介绍 PUN 基础教程是一个基于 Unity 的教程。我们将使用 Photon Cloud 开发第一个简单的 PUN 2 多人游戏。目标是同步每个玩家的动画角色、健康值和基本光线投射。 1.概述 本教程将从一个空项目开始&#xff0c;逐步指导您完成整个创建过程。在此过程中&#xff0c;将解释…

Halcon 形态学 开发案例 (开运算opening(先腐蚀再膨胀)、闭运算closing(先膨胀再腐蚀))

文章目录 1 形态学概念2 开运算 opening2.1 算子介绍2.2 开运算 开发案例3 闭运算 closing3.1 算子介绍3.2 闭运算 开发案例4 示例原图1 形态学概念 图像的形态学处理是对图像的局部像素进行处理,用于从图像中提取有意义的局部图像细节。 通过改变局部区域的像素形态,以对目…

数据结构与算法基础知识

线性结构篇 什么是数据结构与算法 回顾我们之前的C语言程序设计阶段&#xff0c;我们已经接触过基本数据类型&#xff0c;并且能够使用结构体对数据进行组织&#xff0c;我们可以很轻松地使用一个结构体来存放一个学生的完整数据&#xff0c;在数据结构学习阶段&#xff0c;我…

Linux篇1

Linux 1. 概述1.1 内容概要1.2 Linux发展1.3 Linux对比Windows 2. 虚拟机下安装CentOS系统2.1 下载安装VMware2.1.1 官网下载VMware软件2.1.2 安装VMware 2.2 下载CentOS镜像2.3 创建虚拟机&#xff08;在虚拟机中安装CentOS&#xff09;2.3.1 创建虚拟硬件环境2.3.2 安装CentO…

从匆匆的一瞥,到两小时泯灭(SQL注入)

从匆匆的一瞥&#xff0c;到两小时泯灭&#xff08;SQL注入&#xff09; 惊鸿一瞥用户名提示jsBase64.js文件手搓轮子&#xff08;python&#xff09;反复搓轮子&#xff08;python-tamper&#xff09; 惊鸿一瞥 昨天晚上分别开了我相识已久的女友&#xff0c;再度回到了单身狗…

暗月内网靶场渗透笔记

简介 靶场下载地址&#xff1a; 靶场地址&#xff1a; https://pan.baidu.com/s/12pSYxSU-ZmurQ9–GFiaXQ 提取码: 3p47虚拟机网络设置&#xff1a; 靶场拓扑图&#xff1a; 靶机账号密码&#xff1a; 信息收集 内网扫描 靶机就在本地&#xff0c;直接进行本地内网扫描即可…

朋友去华为面试,轻松拿到30K的Offer,羡慕了......

最近有朋友去华为面试&#xff0c;面试前后进行了20天左右&#xff0c;包含4轮电话面试、1轮笔试、1轮主管视频面试、1轮hr视频面试。 据他所说&#xff0c;80%的人都会栽在第一轮面试&#xff0c;要不是他面试前做足准备&#xff0c;估计都坚持不完后面几轮面试。 其实&…

OpenGL高级-几何着色器

几何着色器的介绍 在顶点和片段着色器之间有一个可选的着色器&#xff0c;叫做几何着色器(Geometry Shader)。几何着色器以一个或多个表示为一个单独基本图形&#xff08;primitive&#xff09;的顶点作为输入&#xff0c;比如可以是一个点或者三角形。几何着色器在将这些顶点发…

C++14中lambda表达式新增加的features的使用

lambda表达式是在C11中引入的&#xff0c;它们可以嵌套在其它函数甚至函数调用语句中&#xff0c;C11中lambda表达式的使用参考&#xff1a;https://blog.csdn.net/fengbingchun/article/details/52653313 lambda表达式语法如下&#xff1a;除capture和body是必须的&#xff0c…

索引的作用与结构(数据库)

目录 一、索引概述 1、什么叫索引 2、索引的作用 二、SQL Server索引下的数据组织结构 1&#xff0e;堆集结构 2&#xff0e;聚集索引结构 3&#xff0e;非聚集索引 4&#xff0e;扩展盘区空间的管理 一、索引概述 1、什么叫索引 数据库中的索引与书籍中的索引类似&…

【数据分享】2014-2023年全国各监测站点的逐时、逐日、逐月、逐年AQI数据

空气质量的好坏反映了空气的污染程度&#xff0c;在各项涉及城市环境的研究中&#xff0c;空气质量都是一个十分重要的指标。空气质量是依据空气中污染物浓度的高低来判断的。 我们发现学者王晓磊在自己的主页里面分享了2014年5月以来的全国范围的到站点&#xff08;全国有约2…

小实验:关于期望的乘法性质

小实验&#xff1a;关于期望的乘法性质 引言个人疑惑验证过程样本生成实验过程 附&#xff1a;完整代码 引言 本节通过代码实现期望的乘法性质。 个人疑惑 在数学期望的定义中&#xff0c;有一条随机变量期望的乘法性质&#xff1a; 当随机变量 X , Y \mathcal X,\mathcal Y…

spring如何处理循环依赖

何为循环依赖 所谓的循环依赖&#xff0c;就是两个或者两个以上的bean互相依赖对方&#xff0c;最终形成闭环。比如“A对象依赖B对象&#xff0c;而B对象也依赖A对象”&#xff0c;或者“A对象依赖B对象&#xff0c;B对象依赖C对象&#xff0c;C对象依赖A对象”&#xff1b;类…

MySQL笔记-多表查询

本文标签 : 多表查询 事务四大特性 并发事务问题 事务隔离级别 文章目录 目录 文章目录 一、多表查询 1.多表关系 2.多表查询概念 3.多表查询的分类 4.内连接 5.外连接 6.自连接 7.联合查询 8.子查询 1.标量子查询 2.列子查询 3.行子查询 4.表子查询 9.多表查询案例练习 二…

springboot+vue汉服文化平台网站(源码+文档)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的汉服文化平台网站。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 &#x1f495;&#x1f495;作者&#xff1a;风…

初阶数据结构之带头+双向+循环链表增删查实现(三)

文章目录 [TOC](文章目录) 前言一、带头双向循环链表的初始化1.1带头双向循环链表的结构体定义1.2初始化代码的实现 二、带头双向循环链表的增功能实现2.1头插代码的实现2.2尾插代码的实现 三、带头双向循环链表的打印功能实现3.1打印代码的实现 四、带头双向循环链表删功能实现…

国开电大《WEB开发基础》形考任务【答案】实验1-5:电商网站前端页面内容编写

国开电大《WEB开发基础》形考任务1 国开电大《WEB开发基础》形考任务1 国开电大《WEB开发基础》形考任务3 国开电大《WEB开发基础》形考任务4 国开电大《WEB开发基础》形考任务5 作业答案 联系QQ:1603277115 【目标】根据素材中的设计图&#xff0c;编写网站首页&#xff0c;查…

AcWing算法提高课-1.3.6货币系统

宣传一下算法提高课整理 <— CSDN个人主页&#xff1a;更好的阅读体验 <— 本题链接&#xff08;AcWing&#xff09; 点这里 题目描述 给你一个n种面值的货币系统&#xff0c;求组成面值为m的货币有多少种方案。 输入格式 第一行&#xff0c;包含两个整数n和m。 接…

Vue3-黑马(七)

目录&#xff1a; &#xff08;1&#xff09;vue3-基础-子组件1 &#xff08;2&#xff09;vue3-基础-子组件2 &#xff08;3&#xff09;vue3-进阶-antdv-入门 &#xff08;1&#xff09;vue3-基础-子组件1 之前我们的例子里只使用了一个vue的组件&#xff0c;那么在这个…