运算符重载(五)

目录

  • const成员函数
    • const对象不可以调用非const成员函数
    • 非const对象可以调用const成员函数
    • const成员函数内不可以调用其它的非const成员函数
    • 非const成员函数内可以调用其它的const成员函
  • 取地址及const取地址操作符重载
  • const补充
    • 场景1
    • 场景2
    • 场景3
    • 场景4

const成员函数

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

const对象不可以调用非const成员函数

这是Print函数,当我们用const修饰的对象去调用他时

	void Print()
	{
		cout << _year << "/" << _month << "/" << _day << endl;
	}

在这里插入图片描述
const修饰对象报错常见的就是权限的放大问题
d1被const修饰后是不可以修改,而Print函数传参时是隐藏了this指针的,也就是说print函数传的参数是d1的地址,将d1的地址穿进去后就有可能会修改d1,所以这是权限放大的原因

要解决问题就需要用const去修饰函数

void Print()const
{
	cout << _year << "/" << _month << "/" << _day << endl;
}

这里的const是修饰this指针指向的内容,注意const修饰的方式是void Print()const,而不是const void Print()或void const Print()

如果对于全局函数就不能像上面修饰的一样了
void operator <<(ostream& out) 不能修饰成 operator <<(ostream& out)const
void operator >>(ostream& in,Date &d) 不能修饰成 void operator >>(ostream& in,Date &d)const

要搞清楚const是想要修饰什么,void Print()const修饰的是隐藏的this指针
operator <<(ostream& out)和 void operator >>(ostream& in,Date &d)根本就没有隐藏的this指针,所以不需要在后面加const
即使想要加const也要这样加 void operator >>(ostream& in,const Date &d)(但是这样是错误的,因为流提前要改变对象,所以不应该加const,这里只是演示该加在哪)

非const对象可以调用const成员函数

非const对象可以调用const成员函数是因为d1没有被const修饰,所以他是可读可写的,而Print函数被const修饰后只要求可以读取数据内容,并不要求修改数据,所以当然可以,可以把这里理解成权限的缩小

在这里插入图片描述
要注意对于只要求读取数据的函数可以加上const修饰,但不用让所以函数都被const修饰,因为如果有的函数要求修改数据,加上const后就会出现权限放大问题

总结
成员函数中如果是一个对成员变量只进行读访问的函数建议加上const修饰,这样被const修饰的对象和没变const修饰的对象都可以使用
如果是对成员变量进行读写访问的函数,不能加上const修饰,否则会出现权限放大问题

const成员函数内不可以调用其它的非const成员函数

这里还是权限放大问题,const修饰的成员函数表示这个函数内部都是不可以修改Date的成员变量的,而如果里面出现了非const的成员函数,就表示里面可以修改成员变量,这显然不行

非const成员函数内可以调用其它的const成员函

这是权限缩小,所以可以
总之const修饰后的对象注意一下权限是否变大就行了

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

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

class Date
{
private:
	int _year;
};
class A
{
public:
	A* operator&()
	{
		return this;
	}
	const A* operator&()const
	{
		return this;
	}
};
int main()
{
	A aa1;
	const A aa2;
	cout << &aa1 << endl;
	cout << &aa2 << endl;
	return 0;
}

A* operator&()和const A* operator&()const是想返回this指针,而返回的this指针有差别
A* operator&()对传入的this指针没有进行const修饰,并且返回的this指针也没有进行const修饰
而const A* operator&()const对传入的this指针进行了修饰,并且返回的this指针也进行了const修饰

通过调用这两个函数得到的this指针可以直接打印出this指针的值
在这里插入图片描述
当我们屏蔽掉上面的代码后,也可以正常运行,因为这是默认成员函数,我们不写编译器会生成,而这两个默认成员函数并不像我们之前写的拷贝函数和析构函数等等默认成员函数那样复杂,这两个默认成员函数就是返回一个this指针,所以日常都不需要我们写,编译器默认生成的函数就够用了
在这里插入图片描述
那什么时候是需要我们写的呢?
比如我们只想让被const修饰后的成员函数拿到地址,这样做的目的就是不想有人拿到地址后乱搞

class Date
{
private:
	int _year;
};
class A
{
public:
	A* operator&()
	{
		return nullptr;
	}
	const A* operator&()const
	{
		return this;
	}
};
int main()
{
	A aa1;
	const A aa2;
	cout << &aa1 << endl;
	cout << &aa2 << endl;
	return 0;
}

在这里插入图片描述
甚至我们还可以返回一个假地址

在这里插入图片描述
在这里插入图片描述

const补充

场景1

int main()
{
	const int i = 0;
	int j = i; 
		cout << j << endl;
	return 0;
}

这里j=i没有报错是因为j是i的拷贝,将i的值拷贝给了j
在这里插入图片描述

场景2

int main()
{
	const int i = 0;
	int& r = i; 
		cout << r << endl;
	return 0;
}

这里的r是i的别名,r被修改会导致i也会被修改,所以报错
在这里插入图片描述

场景3

int main()
{
	int i = 0;
	const int* p1 = &i;
	int* p2 = p1;
	return 0;
}

const修饰p1表示不可以通过p1去修改p1指向的值i,换句话来说就是不可以修改p1
在这里插入图片描述
但是可以修改p1指向的地址,也就是p1可以被修改
在这里插入图片描述
上面的代码中 int
p2 = p1是想将p1指向的地址传给p2,而p1指向的地址是&i
根据前面的结论,const修饰p1表示p1不可以被修改,而p1将i的地址给了p2,p2就可以通过p1给的地址去修改i,也就间接的使*p1修改了,所以才会报错

在这里插入图片描述

场景4

int main()
{
	int i = 0;
	int* const  p1 = &i;
	int* p2 = p1;
	return 0;
}

const修饰p1表示p1不可以被修改,因为p1是一个指针,而p1保存的是i的地址,p1不能被修改意思就是i的地址不可以修改

将p1的值给p2,这里并不会报错,我猜测可能p2也是拷贝了p1的地址,所以p2的改变不会影响p1
在这里插入图片描述
如果想让上面的代码报错,我们可以修改p1,让p1保存另一个变量j的地址,因为const修饰的是p1,p1是不能变的,所以就会报错
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

redis之RedisTemplate和StringRedisTemplate的区别

1.RedisTemplate和StringRedisTemplate的区别 StringRedisTemplate继承RedisTemplate 两者的数据是不共通的&#xff08;默认的序列化机制导致key不一样&#xff09; StringRedisTemplate默认采用的是String的序列化策略 RedisTemplate默认采用的是JDK的序列化策略&#xf…

浅探 Windows 上获取磁盘信息的几种方式(一)

获取磁盘信息是一个常见需求&#xff0c;如检查磁盘预留空间&#xff0c;开发磁盘碎片整理工具&#xff0c;系统性能优化等工具等。 Windows 为此提供了各种接口&#xff0c;今天我们主要讲讲常用相关的三个API &#xff1a; GetDiskFreeSpaceGetDiskFreeSpaceExGetDiskSpaceI…

通信综合—8.通信网络安全

一、信息系统安全概述 1.信息系统的构成和分类 信息系统是将用于收集、处理、存储和传播信息的部件组织在一起而成的相关联的整体&#xff0c;般是由计算机硬件、网络和通信设备、计算机软件、信息资源和信息用户组成。它是以处理信息流为目的的人机一体化系统。信息系统主要…

语言的艺术:探秘基于GPT模型的文本生成与优化之美

语言的艺术&#xff1a;探秘基于GPT模型的文本生成与优化之美 在人工智能蓬勃发展的今天&#xff0c;语言模型如同文字艺术的魔术师&#xff0c;赋予了计算机以“书写”的能力。基于GPT&#xff08;Generative Pre-trained Transformer&#xff09;模型的文本生成技术&#xf…

微服务篇-深入了解 XA 模式与 AT 模式、分布式事务(部署 TC 服务、微服务集成 Seata )

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 分布式事务 1.1 认识 Seata 2.0 部署 TC 服务 2.1 准备数据库表 2.2 准备配置文件 2.3 Docker 部署 3.0 微服务集成 Seata 3.1 引入依赖 3.2 改造配置 3.3 添加数…

王道考研编程题总结

我还在完善中&#xff0c;边复习边完善&#xff08;这个只是根据我自身总结的&#xff09; 一、 线性表 1. 结构体 #define MaxSize 40 typedef struct{ElemType data[MaxSize]&#xff1b;int length; }SqList 2. 编程题 1. 删除最小值 题意 &#xff1a;从顺序表中删除…

原生html+css+ajax实现二级下拉选择的增删改及树形结构列出

<?php $db_host localhost; $db_user info_chalide; $db_pass j8c2rRr2RnA; $db_name info_chalide; /* 数据库结构SQL CREATE TABLE categories ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255) NOT NULL, parent_id INT DEFAULT 0 ); */ try { $pdo new PD…

微信小程序介绍-以及写项目流程(重要)

前言&#xff1a;本篇文章介绍微信小程序以及项目介绍&#xff1a; 文章介绍&#xff1a;介绍了微信小程序常用的指令、组件、api。tips&#xff1a;最好按照官方文档来进行学习&#xff0c;大致可以我的目录来学习&#xff0c;对于写项目是没有问题的 微信小程序官方文档https…

Data Uncertainty Learning in Face Recognition 论文阅读

Data Uncertainty Learning in Face Recognition 论文阅读 Abstract1. Introduction2. Related Work3. Methodology3.1. Preliminaries3.2. Classification-based DUL for FR3.3. Regression-based DUL for FR3.4. Discussion of Related Works 4. Experiments4.1. Datasets an…

汽车产业数字化转型:协同创新破解挑战,平衡安全与流通

在数字经济时代的浪潮中&#xff0c;数据资源和数据信息已成为驱动各行各业转型升级的“新石油”。汽车产业&#xff0c;作为国民经济的重要支柱&#xff0c;正经历着前所未有的变革。随着数字化创新和转型的深入&#xff0c;数据在汽车全产业链中的作用和价值日益凸显。在这个…

vulnhub kioptirx1.2 超详细wp

探测 nmap --min-rate 10000 -p- 192.168.128.134 最小速率10000 nmap -sT -sV -sC -O 192.168.128.134 web打点 无弱口令 暴露cms寻找exp searchsploit LotusCMS -m 16982 [输入id号和参数m可以直接把东西复制到当前目录] 查看txt里面发现 都是xss没有rce github搜索到一个…

扫二维码进小程序的指定页面

草料二维码解码器 微信开发者工具 获取二维码解码的参数->是否登陆->跳转 options.q onLoad: function (options) {// console.log("options",options.q)if (options && options.q) {// 解码二维码携带的链接信息let qrUrl decodeURIComponent(optio…

mysql基础学习1

useradd -r -g mysql -s /bin/false mysql (-r)系统用户 不能登录 A temporary password is generated for rootlocalhost: d>#jT7rfoaz) 看是否启动 看进程 端口 直接连接 看日志 varchar (20) char(20)更耗空间 create table student_info(id int,name varchar(20),s…

Echarts使用平面方法绘制三维立体柱状图表

目录 一、准备工作 1.下载引入ECharts库 2.创建容器 二、绘制基本柱状 三、绘制立体柱状方法一 1.定义立方体形状 2.注册立方体形状 3.配置custom系列 4.设置数据 5.渲染图表 四、绘制立体柱状方法二 1.画前知识 2.计算坐标renderItem 函数 &#xff08;1&#x…

基于 MindQuantum 实现对 “天衍” 量子云平台真机的比特映射

MindQuantum 目前只支持量子模拟器&#xff0c;如果需要获得量子算法在真机上的实测数据&#xff0c;可以借助“天衍”量子云平台提供的真机。本文将介绍如何基于 MindQuantum 绘制“天衍”真机的拓扑图&#xff0c;并进而实现比特映射。 关于 MindQuantum 涉及比特映射的教程…

OpenBayes贝式计算创始人受邀参加第九届中国开源年会,分享 AI4S 前沿洞察

Open Source&#xff0c;Open Life&#xff0c;开源新生活&#xff01; 由开源社主办的第九届中国开源年会 (COSCon24) 于 2024 年 11 月 3 日在北京圆满落幕。本届大会为期 2 天&#xff0c;以 「开源新生活 - Open Source, Open Life 」 为主题&#xff0c;汇聚了来自全国各…

Day1 生信新手笔记

生信新手笔记 生信学习第一天笔记打卡。 转录组学中&#xff1a; 上游分析-基于linux&#xff0c;包括质控、过滤、比对、定量&#xff1b; 下游分析-基于R语言&#xff0c;包括差异分析、富集分析、可视化。 1. 级别标题 一个井号加空格 就是一级标题&#xff0c;两个井号加…

日拱一卒(9)——leetcode学习记录:两数组中位数

一、问题 给定两个大小分别为 m 和 n 的排序数组 nums1 和 nums2&#xff0c;要求你在 O(log(mn)) 的时间复杂度内找出这两个数组的中位数。 二、思路 时间复杂度O(log(n))代表随着操作数增加&#xff0c;剩余操作数递减&#xff0c;如二分法。 首先要建模&#xff0c;对这…

从 HTML 到 CSS:开启网页样式之旅(五)—— CSS盒子模型

从 HTML 到 CSS&#xff1a;开启网页样式之旅&#xff08;五&#xff09;—— CSS盒子模型 前言一、盒子模型的组成margin&#xff08;外边距&#xff09;&#xff1a;border&#xff08;边框&#xff09;&#xff1a;padding&#xff08;内边距&#xff09;&#xff1a;conten…

【区块链】深入理解区块链中的 Gas 机制

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 深入理解区块链中的 Gas 机制一、Gas 的基本概念1.1 为什么需要 Gas&#xff1f…