C++类与对象(三)赋值运算符重载、const成员

news2024/11/25 1:03:10

目录

1.赋值运算符重载

1.1引入

1.2 运算符重载

1.3赋值运算符重载

1.4 前置++和后置++重载

2.const成员

3.取地址及const取地址操作符重载


1.赋值运算符重载

1.1引入

赋值运算符重载:用已存在的对象,给另一个已存在的对象赋值

还是使用上节日期类的代码,在测试中如下操作:

class Date
{
public:
	Date(int year = 2000, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
		cout << "Date(int,int,int):" << this << endl;
	}
	Date(const Date& d)
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
		cout << "Date(const Date& d):" << this << endl;
	}
	~Date()
	{
		cout << "~Date():" << this << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};
void TestDate()
{
	Date d1(2022,11,15);//构造函数
	Date d2(d1);	//拷贝构造函数

	Date d3;//用的默认的参数,创建的时候没给实参
	d3 = d2; //用已存在的对象,给另一个已存在的对象赋值,

	Date d4 = d3;//拷贝构造
}

 语法:如果程序员没有显示定义赋值运算符重载,则编译器会自动生成一份

实际情况:编译器不一定会生成,但是编译器一定会完成赋值的操作

如果类中未涉及到资源管理,赋值运算符是否实现都可以;但是, 一旦涉及到资源管理则必须要实现 ,比如栈的代码,当进行以下操作时:

这时候会出现浅拷贝,导致内存泄漏问题,那么为了解决这个问题,就需要使用 赋值运算符重载方法,下面依次进行学习

1.2 运算符重载

还是从代码来学习:

需求:检测两个日期类型对象是否相等(用的还是上面日期类代码,修改部分如下)

	//需求:检测两个日期类型对象是否相等
	bool IsEqual(const Date& d)
	{
		return _year == d._year &&
		_month == d._month &&
		_day == d._day;
	}

int main()
{
	Date d1(2022, 11, 15);
	Date d2(d1);
	if (d1.IsEqual(d2))
	{
		cout << "d1 == d2" << endl;
	}
	else
	{
		cout << "d1 != d2" << endl;
	}


//上面不直观,要是使用==如下
if (d1==d2)
	{
		cout << "d1 == d2" << endl;
	}
	else
	{
		cout << "d1 != d2" << endl;
	}

	return 0;
}
使用==会报错,所以注意,自定义类型不支持 == 的运算符,因为编辑器不知道怎么比较
如果一定要使用 == 来比较自定义类型对象, 必须告诉编译器比较的规则--->运算符重载

修改上述代码

bool operator==(const Date& d)
	{
		return _year == d._year &&
			_month == d._month &&
			_day == d._day;
	}

if (d1==d2)//与if(d1.operator(d2))等价
	{
		cout << "d1 == d2" << endl;
	}
	else
	{
		cout << "d1 != d2" << endl;
	}

C++为了增强代码的可读性引入了运算符重载运算符重载是具有特殊函数名的函数 也具有其返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。
函数名字为:关键字 operator 后面接需要重载的运算符符号
函数原型: 返回值类型  operator 操作符 ( 参数列表 )
注意:
1.在operator后面跟的必须是C++支持的运算符,不能通过连接其他符号来创建新的操作符:比如operator@,
2.重载操作符必须有一个类类型参数
3.用于内置类型的运算符,其含义不能改变,例如:内置的整型+,不 能改变其含义
4.作为类成员函数重载时,其形参看起来比操作数数目少1,因为成员函数的第一个参数为隐藏的this
5.   .*   ::    sizeof    ? :     .        注意以上5个运算符不能重载。这个经常在笔试选择题中出现。

1.3赋值运算符重载

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

Date& operator=(const Date& d)
 {
     if(this != &d)
     {
     _year = d._year;
     _month = d._month;
     _day = d._day;
     }
     return *this;
 }
2. 赋值运算符只能重载成类的成员函数不能重载成全局函数

原因:赋值运算符如果不显式实现,编译器会生成一个默认的。此时用户再在类外自己实现一个全局的 赋值运算符重载,就和编译器在类中生成的默认赋值运算符重载冲突了,故赋值运算符重载只能是类的成员函数

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

1.4 前置++和后置++重载

// 前置 ++ :返回 +1 之后的结果
// 注意: this 指向的对象函数结束后不会销毁,故以引用方式返回提高效率
Date& operator++()
 {
 _day += 1;
 return *this;
 }

// 后置++

// 前置 ++ 和后置 ++ 都是一元运算符,为了让前置 ++ 与后置 ++ 形成能正确重载
// C++ 规定:后置 ++ 重载时 多增加一个int类型的参数 但调用函数时该参数不用传递,编译器自动传
// 注意:后置 ++ 是先使用后 +1 ,因此需要返回 +1 之前的旧值,故需在实现时需要先将 this 保存一份,然后给this+1
// temp 是临时对象,因此只能以值的方式返回,不能返回引用
Date operator++(int)
 {
 Date temp(*this);
 _day += 1;
 return temp;
 }
int main()
{
 Date d;
 Date d1(2022, 1, 13);
 d = d1++; // d: 2022,1,13 d1:2022,1,14
 d = ++d1; // d: 2022,1,15 d1:2022,1,15
 return 0;
}

2.const成员

将const修饰的“成员函数”称之为const成员函数,const修饰类成员函数,实际修饰该成员函数隐含的this指针,表明在该成员函数中 不能对类的任何成员进行修改

A.普通成员函数:没有被const修饰的成员函数

在该成员函数中,可以对对象成员变量进行修改

this类型:Date*  const  ----》this的指向不能修改,this指向空间的内容可以修改

可写入:可以修改成员变量

void show()
	{
		_day += 1;
		this->_day += 1; //与上面等价

		cout << _year << "/" << _month << "/" << _day << endl;
	}

B const成员函数:被const修饰的成员函数

特性:不能修改“成员变量”

const修饰成员函数实际实在修饰this指针

this的类型:const Date* const

只读:只能读取this中成员,不能修改

注意:如果成员函数内部不一定会修改成员变量,最后将该成员设置const函数

class Date
{
public:
	Date(int year = 2000, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}

    void show()
	{
		_day += 1;
		this->_day += 1; //与上面等价

		cout << _year << "/" << _month << "/" << _day << endl;
	}
	//const成员函数:被const修饰的成员函数
	//特性:不能修改“成员变量”
	//const修饰成员函数实际实在修饰this指针
	//this的类型:const Date* const
	void Print()const
	{
		cout << _year << "/" << _month << "/" << _day << endl;
	}

private:
	int _year;
	int _month;
	int _day;
};


int main()
{
	//普通对象d1可读可写,既可以调用普通成员函数也可以调用const成员函数
	Date d1(20022, 12, 2);
	d1.show();
	d1.Print();

	//const对象d2只读,只能调用const成员函数,只读不能写
	const Date d2(d1);
	d2.Print();
	return 0;
}
请思考下面的几个问题:
1. const对象可以调用非const成员函数吗?
const对象不能修改调用普通成员函数
2. 非const对象可以调用const成员函数吗?
可以
3. const成员函数内可以调用其它的非const成员函数吗?
不可以
4. 非const成员函数内可以调用其它的const成员函数吗?

可以

3.取地址及const取地址操作符重载

class Date
{ 
public :
 Date* operator&()
 {
 return this ;
 }
 
//this的类型就是const Date* const
 const Date* operator&()const
 {
 return this ;
 }
private :
 int _year ; // 年
 int _month ; // 月
 int _day ; // 日
};
int main()
{
	
	Date d1(20022, 12, 2);
	
	//需求:在对对象取地址的时候需要将地址打印出来
	Date* p = &d1;

	
	return 0;
}
这两个运算符一般不需要重载,使用编译器生成的默认取地址的重载即可,只有特殊情况,才需要重载,比如想让别人获取到指定的内容

 

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

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

相关文章

[网络工程师]-应用层协议-电子邮件协议

常见的电子邮件协议有简单邮件传输协议、邮局协议和Internet邮件访问协议。 1、简单邮件传输协议&#xff08;Simple Mail Transfer Protocol&#xff0c;SMTP&#xff09; SMTP主要负责将电子邮件从发送方传送到接收方&#xff0c;即对传输的规则做了规定&#xff0c;该协议工…

2023最新SSM计算机毕业设计选题大全(附源码+LW)之java医院疫情管理系统4f9a9

毕业设计其实不难&#xff0c;主要毕业的时候任务太紧了&#xff0c;所以大家都非常忙没有时间去做&#xff0c;毕业设计还是早做准备比较好&#xff0c;多花点时间也可以做出来的&#xff0c;建议还是自己动手去做&#xff0c;比如先选一个题&#xff0c;这样就有方向&#xf…

Markdown 图片左右对齐、居中、大小设置

Markdown 图片左右对齐、居中、大小设置 虽然经常使用 Markdown 写博客&#xff0c;但是&#xff0c;我却不太知道 Markdown 图片的位置和大小设置&#xff0c;今天刚好发表博客的时候&#xff0c;发觉图片位置有点丑&#xff0c;Google 查到了方法&#xff0c;所以记录学习一下…

李立宗《计算机视觉40例》PPT课件:第3章

《计算机视觉40例》PPT课件&#xff1a;第3章 《计算机视觉40例》第3章是OpenCV入门&#xff0c;这一章对OpenCV的使用进行了简单的介绍。这章目录如下&#xff1a; 本章集中介绍了OpenCV中一些最通用的知识&#xff0c;这些知识在后面的案例中应用比较广泛&#xff0c;所以集…

木聚糖-聚乙二醇-牛血清白蛋白,BSA-PEG-Xylan,牛血清白蛋白-PEG-木聚糖

木聚糖-聚乙二醇-牛血清白蛋白,BSA-PEG-Xylan,牛血清白蛋白-PEG-木聚糖 中文名称&#xff1a;木聚糖-牛血清白蛋白 英文名称&#xff1a;Xylan-BSA 纯度&#xff1a;95% 别称&#xff1a;牛血清白蛋白修饰木聚糖&#xff0c;BSA-木聚糖 PEG接枝修饰木聚糖 木聚糖-聚乙二醇…

Mysql——》decimal

推荐链接&#xff1a; 总结——》【Java】 总结——》【Mysql】 总结——》【Redis】 总结——》【Kafka】 总结——》【Spring】 总结——》【SpringBoot】 总结——》【MyBatis、MyBatis-Plus】 Mysql——》decimal一、作用二、语法三、示例一、…

ADSP-21489的开发详解:VDSP+自己编程写代码开发(8-延时算法)

这个程序&#xff0c;对 48Khz 或 96Khz 采样率的音频&#xff0c;进行了延时处理&#xff0c;并输出。跑程序和上面的例程一样&#xff0c;我们来看一下他音频处理部分的具体程序。&#xff08;音频输入输出需根据程序换接口&#xff09; Left_Channel_Out1 Left_Channel_In2…

MEI 论文笔记

Multi-Partition Embedding Interaction with Block Term Format for Knowledge Graph Completion- Introduction- Algorithm- Experiment- Conclusion- CodeHung-Nghiep Tran, Atsuhiro Takasu - Introduction 以前的工作通常将每个嵌入视为一个整体&#xff0c;并对这些整体…

元宇宙产业委共同主席倪健中:打开元宇宙的潘多拉魔盒,释放元宇宙产业无限的想象与发展空间|平安银行元宇宙与新终端创新沙龙

12 月 2 日&#xff0c; 平安银行携手业内元宇宙知名专家学者、行业投资人、新终端企业代表在深圳蛇口举办“洞见未来超前领航——2022 平安银行元宇宙与新终端创新沙龙”&#xff0c;共同探讨虚拟现实的多样性&#xff0c;畅游元宇宙时空下的科技文明&#xff01; 活动开场&am…

VSCode使用Qt的MinGW作为编译器编译C++

一、起因 我本人已经安装了Qt、VS、VSCode&#xff0c;因此不想再安装其他的编译器&#xff0c;但又想使用VSCode直接编译&#xff0c;所以就想看一下能否VSCode能否直接使用Qt的编译器。经过实验的确是可以的&#xff0c;这样就无需再下载MinGW-w64&#xff0c;其实我也有下载…

mongodb6创建账号

目录一、创建管理员账号二、创建普通账号一、创建管理员账号 无权限登录mongodb&#xff08;即官方默认配置登录&#xff09; mongosh --host 127.0.0.1 --port 27017创建管理员账号 #切换到admin数据库 use admin #创建admin账号 db.createUser({user:"testAdmin"…

22年下半年软考考后成绩查询、分数线、证书领取相关注意事项

一、软考成绩查询时间 软考考试时间分为上半年和下半年&#xff0c;上半年固定是在五月份下半年固定是在十一月份。 成绩查询时间一般在考试时间后的两个月左右根据历年来看&#xff0c; 2022年上半年软考考试时间是5月28-29日&#xff0c;成绩7月中旬左右在官网可以查询&am…

聊天信息框显示消息

聊天信息框显示消息 效果展示 概述 本文讲解如何制作&#xff0c;可以提交信息的聊天框&#xff0c;并且可以删除已经发布的聊天信息。 构建HTML框架 <body><textarea name"" id""></textarea><button>发布</button><…

基于java(ssm)学生在线课程学习系统源码(java毕业设计)

基于java&#xff08;ssm&#xff09;学生在线课程学习系统 学生在线课程学习系统是基于java编程语言&#xff0c;mysql数据库&#xff0c;ssm框架&#xff0c;和idea工具开发&#xff0c;本项目主要分为学生&#xff0c;管理员两个角色&#xff0c;学生的功能是登陆&#xff…

移动端抓包

1.手机连接电脑&#xff08;处于一个局域网&#xff09; 手机、电脑连接同一个WIFI电脑通过网线连接无线路由&#xff0c;手机连接这个WIFI手机开热点&#xff0c;电脑连接这个热点 2.Fiddler 代理 开启Fiddler代理&#xff0c;tools——Options——Connections——Allow re…

【C++】单例模式

目录 1.如何提供一个全局变量来记录函数调用次数呢&#xff1f; 2.1饿汉模式 2.2懒汉模式 2.2.1实现一个内嵌垃圾回收类 懒汉的另一种写法 1.如何提供一个全局变量来记录函数调用次数呢&#xff1f; 声明定义分离 func.h extern int Count ;//声明 func.cpp #include "…

如何实现人机界面与多台plc之间无线通讯?

本文将以MCGS触摸屏与三菱FX5U PLC基于MODBUS协议下的无线通信为例&#xff0c;为大家详细讲解如何用无线方式解决触摸屏与PLC之间的通讯问题。 测试设备与参数 1. 三菱PLC型号&#xff1a;FX5U *1台 2. 触摸屏型号&#xff1a;昆仑通态TPC7062TD *1台 3. 无线通讯设备&…

Nginx中配置GZIP压缩详解

网站访问速度对用户来说是很重要的体验&#xff0c;有时候除了增大带宽外&#xff0c;还需要对文件进行压缩。 首先找到Nginx安装路径下的配置文件&#xff1a; 保存后&#xff0c;使用nginx -t检查配置文件是否OK&#xff1a; 上述报错证明nginx在编译安装时候没有连同http_s…

Grafana+Prometheus打造运维监控系统(二)-数据获取篇-node_exporter

要实现各种数据指标采集&#xff0c;需要安装不同的数据导出器&#xff0c;常用的导出器有node_exporter、process-exporter、blackbox_exporter&#xff0c;这里简单讲一下node_exporter&#xff0c;node_exporter安装参考上篇&#xff1a;https://blog.csdn.net/zcm545186061…

SpringCloud Nacos入门教程

服务发现和服务健康监测 动态配置服务 动态DNS服务 服务及其元数据管理 二、Nacos快速开始 结构图&#xff1a; Nacos 依赖 Java 环境来运行。如果您是从代码开始构建并运行Nacos&#xff0c;还需要为此配置 Maven环境&#xff0c;请确保是在以下版本环境中安装使用: 64 …