【C++】类的默认成员函数----const成员函数(超详细解析)

news2025/7/10 4:02:12

目录

一、前言

二、const成员函数 

🍎const修饰类的成员函数 

💦问题1 

💦问题2

💦针对const成员函数的常考面试题(重点!!)

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

三、共勉


一、前言

   在我们前面学习的中,我们会定义成员变量成员函数,这些我们自己定义的函数都是普通的成员函数,但是如若我们定义的类里什么也没有呢?是真的里面啥也没吗?如下:

class Date {};

  如果一个中什么成员都没有,简称为空类。空类中什么都没有吗?并不是的任何一个类在我们不写的情况下,都会自动生成6个默认成员函数。


【默认成员函数概念】:用户没有显式实现,编译器会生成的成员函数称为默认成员函数


⭐其中上次的博客已经详细的讲解了构造函数&&析构函数的使用方法与拷贝构造函数和赋值运算符重载,所以本次博客将继续深度的讲解const成员函数问题

二、const成员函数 

🍎const修饰类的成员函数 

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

💦问题1 

 假如我现在有一个日期类,并且有如下的Func函数即调用情况:

class Date
{
public:
	//构造函数
	Date(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void Printf()
	{
		cout << _year << "年" << _month << "月" << _day << "日" << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};

void Func(const Date& d)
{
	d.Printf();
}

int main()
{
	Date d1(2023, 11, 1);
	d1.Printf();
	Date d2(2023, 11, 2);
	Func(d2);
	return 0;
}

此时却出现了报错,这是为什么呢?

很明显,这里Func函数d的调用Print()出错了,而d1调用Print()却没出错,为何呢?

这里涉及到权限问题。我们先把实际调用过程中,隐含的this指针写出来:
如果对 this指针不了解的朋友可以看这篇博客:this 指针详解


Print()函数里的const修饰this本身,this不能修改,但是this可以初始化,接着我们要搞清楚&d1和&d的类型分别是啥:

  • &d1:Date*
  • &d:const Date*
  1. Date*传给Date* const没有问题,都是可读也可修改,所以d1调用Print()不会出错
  2. 而const Date* 指向的内容不能被修改,可是当它传给Date*时就出错了,因为Date*是可以修改的,这里传过去会导致权限放大。所以当然d调用Print()函数报错。



 

⭐解决办法: 
加上const去保护this指向的内容,也就是在Date*的前面加上const:

void Print(const Date* const this)
{
	cout << _year << "年" << _month << "月" << _day << "日" << endl;
}

但是这里又不能之间加上const,因为this指针是隐含的,你不能显示的将const写出来。因此,C++为了解决此问题,允许在函数后面加上const以达到刚才的效果:
 

void Print() const// 编译器默认处理成:void Print(const Date* const this)
{
	cout << _year << "-" << _month << "-" << _day << endl;
}

此时我const Date*传给const Date*就是权限不变,自然不会出错了,同样我Date*传给const Date*就是权限缩小也不会有问题。因为权限不能放大,只能缩小或不变。

正确的代码:

class Date
{
public:
	//构造函数
	Date(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void Printf()  const     // void Printf(Date* const this)
	{
		cout << _year << "年" << _month << "月" << _day << "日" << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};

void Func(const Date& d)
{
	d.Printf();   // d.Printf(&d);
}

int main()
{
	Date d1(2023, 11, 1);
	d1.Printf();           // d1.Printf(&d);
	Date d2(2023, 11, 2);
	cout << endl;
	Func(d2);
	return 0;
}


 

 💦问题2

假如我们遇到如下,自定义类型的比较情况:

class Date
{
public:
	//构造函数
	Date(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	bool operator<(const Date& d)
	{
		if (_year < d._year ||
			_year == d._year && _month < d._month ||
			_year == d._year && _month == d._month && _day < d._day)
		{
			return true;
		}
		else
		{
			return false;
		}
	}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Date d1(2023, 11, 1);
	const Date d2(2023, 11, 2);
	cout << endl;
	d1 < d2;
	d2 < d1;
	return 0;
}

此时却出现了报错,这是为什么呢?

  • 首先对于第一个比较来说d1d2都是权限的保持
  • 接着对于第二个比较来说d1传递过去是权限的缩小,本来是可以修改了,现在不能修改;d2传递过去就变成了【权限的放大】,原本的d2const,但是this指针并没有加[const]做修饰,所以就造成了【权限方法】的问题

        那要怎么去做一个修改呢?此时就可以使用到我们上面所讲到的【const成员函数】,为当前的隐藏形参this 加上一个const做修饰,此时就可以做到【权限保持】

bool operator<(const Date& d) const

 💦针对const成员函数的常考面试题(重点!!)

问题1:const对象 可以调用 非const成员函数吗?


        这个当然不可以。我们前面已经说过了,若 const对象去调用非const成员函数,会造成【权限放大】的现象,原本在类外const对象的内容是不可以修改的,但是到了函数内部却有可以修改了,这是不被允许的

 问题2:非const对象 可以调用 const成员函数吗?


        这个当然是可以的。非const对象本身就是可读可写的,那在函数内部你要去修改或者不修改都不会有影响

 问题3:const成员函数内可以调用其它的非const成员函数吗?

       

       不可以,const成员函数内部只能调用const成员函数。因为const成员函数内部的this指针已经具有常属性的,万一这个非const成员函数去修改了成员变量的内容就会出问题了

 问题4:非const成员函数内可以调用其它的const成员函数吗?


       可以,权限缩小
 

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

class Date
{
public:
    //取地址&重载
	Date* operator&()
	{
		return this;
	}
    //const取地址&重载
	const Date* operator&()const
	{
		return this;
	}
private:
	int _year;
	int _month;
	int _day;
};

当然,如果我们自己不写&重载,编译器也会默认生成,可以通过打印来看看:

三、共勉

         以下就是我对【C++】类的默认成员函数----const成员函数的理解,如果有不懂和发现问题的小伙伴,请在评论区说出来哦,同时我还会继续更新对C++ 类和对象的理解,请持续关注我哦!!!  

 

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

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

相关文章

可靠的互联网兼职平台,平常可以做副业充实生活

在互联网时代&#xff0c;越来越多的人开始通过网络来寻找兼职副业的机会&#xff0c;能够更灵活地安排自己的时间&#xff0c;实现自己的收入增值。那么找到一个正规可靠的线上兼职平台就是一个比较重要的事情&#xff0c;这里分享几个正规靠谱的线上兼职副业平台&#xff0c;…

生物信息学 | 借助 AI 更高效地开启研究

生物信息学 (Bioinformatics) 是指利用应用数学、信息学、统计学和计算机科学的方法&#xff0c;研究生物学问题。 随着计算机科学技术的发展&#xff0c;AI 在解决复杂又颇具挑战的生物学研究问题方面&#xff0c;显露出极大的优势&#xff0c;进一步加速了传统研究范式的转变…

京东h5st逆向 h5st代码之拓展

知识点 node安装模块 crypto-js JavaScript 中的加密库 则更偏向于消息摘要算法、对称加密和简单的哈希函数&#xff0c;支持 AES、DES、SHA-1、HMAC 等诸多算法&#xff0c;适用于对客户端本地存储的数据进行加密、散列或签名处理等场景 axios 一旦安装成功&#xff0c;我们就…

uniapp原生插件之视频图片选择安卓原生插件

插件介绍 本地相册图片和视频多选Android扩展原生插件 插件地址 视频图片选择安卓原生插件 - DCloud 插件市场 超级福利 uniapp 插件购买超级福利 插件申请权限 存储卡读写权限 manifest.json权限列表 /* android打包配置 */"android" : {"permission…

python和java区别

1.java需要javac编译为.class文件&#xff0c;用java运行&#xff0c;定义的类需要与文件名相同&#xff1b;python能直接运行&#xff1b;不过&#xff0c;现在java的jdk中能直接使用java直接运行.java文件了&#xff01; 2. java声明变量数据类型&#xff0c;使用int a 8&am…

k8s调度约束

List-Watch Kubernetes 是通过 List-Watch的机制进行每个组件的协作&#xff0c;保持数据同步的&#xff0c;每个组件之间的设计实现了解耦。 List-Watch机制 工作机制&#xff1a;用户通过 kubectl请求给 APIServer 来建立一个 Pod。APIServer会将Pod相关元信息存入 etcd 中…

Jetson NX FFmpeg硬件编解码实现

最近在用Jetson Xavier NX板子做视频处理,但是CPU进行视频编解码,效率比较地下。 于是便考虑用硬解码来对视频进行处理。 通过jtop查看,发现板子是支持 NVENC硬件编解码的。 1、下载源码 因为需要对ffmpeg进行打补丁修改,因此需要编译两份源码 1.1、编译jetson-ffmpeg …

Polygon MidenVM中的recursive STARK verification优化

1. 引言 本文主要参考Bobbin Threadbare 2023年9月在ZK Summit 10上的分享 ZK10: Optimizing recursive STARK verification in Polygon Miden VM - Bobbin Threadbare。 本文基本内容框架为&#xff1a; STARK递归方法Miden需求及目标递归verifier开销Miden VM优化措施结果…

YOLOv7优化:独家创新(SC_C_Detect)检测头结构创新,实现涨点 | 检测头新颖创新系列

💡💡💡本文独家改进:独家创新(SC_C_Detect)检测头结构创新,适合科研创新度十足,强烈推荐 SC_C_Detect | 亲测在多个数据集能够实现大幅涨点 收录: YOLOv7高阶自研专栏介绍: http://t.csdnimg.cn/tYI0c ✨✨✨前沿最新计算机顶会复现 🚀🚀🚀YOLOv7自研…

JS加密/解密之XX数据后台列表JS加密

目标地址 ZHkuZmVpZ3VhLmNu 需求 老朋友联系到我&#xff0c;希望能自己做一个方便读取的小工具给公司内部用&#xff0c;承诺绝不外传。但是获取接口数据的最后一步遇到了问题&#xff0c;响应回来的数据做了大量加密&#xff0c;无法识别。 代码分析 该站代码做了大量的…

MS-VS C# 简单开发记录(GUI)1 -从一个菜单点击打开新窗口

前言&#xff1a; C# 的使用&#xff0c;似乎在机器视觉的集成项目里面变得越来越多了&#xff0c;笔者无奈的熟悉起来这个环境&#xff0c;不过&#xff0c;据说&#xff0c;如果做界面的设计&#xff0c;C#的使用是异常方便的&#xff0c;有的不行了&#xff0c;做几个实例看…

如何在Linux命令行界面愉快进行性能测试?

本人在做性能测试的过程中&#xff0c;遇到一个问题&#xff0c;测试机选了一台Linux服务器&#xff0c;只有命令行界面。执行测试用例不是非常的灵活&#xff0c;有时候我需要改一两个参数添加一些日志&#xff0c;都需要重新打包部署&#xff0c;虽然自动化构建比较方便&…

坚持#第420天~阿里云轻量服务器内存受AliYunDunMonito影响占用解决方法

阿里云轻量服务器内存受AliYunDunMonito影响占用解决方法&#xff0c;亲测有效&#xff1a; Mobax好卡啊&#xff0c;那就直接在阿里云后台操作即可&#xff0c;阿里云后台也可以上传文件。 Navicat mysql好卡啊&#xff0c;那就直接在阿里云后台最上面帮助的右边有个数据库&…

vscode插件安装

Error Lens错误提示 One Dark Pro代码颜色主题

区块链与教育:颠覆传统,引领未来

区块链与教育&#xff1a;颠覆传统&#xff0c;引领未来 摘要&#xff1a;本文将探讨区块链技术在教育领域的应用及其潜在影响。通过介绍区块链技术的基本原理、教育领域的现状&#xff0c;以及区块链技术在教育中的实际应用案例&#xff0c;我们将展望一个去中心化、安全可信…

NI-9219 100 S/s/ch国产化4通道C系列通用多功能模拟输入模块,支持多种传感器

100 S/s/ch&#xff0c;4通道C系列通用模拟输入模块 NI-9219专为多功能测试而设计。NI-9219可用于测量来自多种传感器&#xff08;如应变计&#xff0c;电阻温度检测器(RTD)&#xff0c;热电偶&#xff0c;测压元件和其他有源传感器等&#xff09;的信号&#xff0c;以及制作1…

如何确认目标期刊被SCI或EI收录?

原创内容&#xff0c;仅供参考&#xff0c;欢迎大家批评指正&#xff01; 目录 通过Web of Science查询SCI期刊1. 登录Web of Science2. 查找目标期刊3. 查看期刊信息 通过Scopus查询EI期刊1. 登录Scopus2. 查找目标期刊3. 查看期刊信息 参考 通过Web of Science查询SCI期刊 1…

518年会抽奖软件,支持超高的照片滚动速度

518抽奖软件简介 518抽奖软件&#xff0c;518我要发&#xff0c;超好用的年会抽奖软件&#xff0c;简约设计风格。 包含文字号码抽奖、照片抽奖两种模式&#xff0c;支持姓名抽奖、号码抽奖、数字抽奖、照片抽奖。(www.518cj.net) 照片缓存&#xff0c;支持高速滚动 1. 支持…

05 # 手写 bind

bind 干了什么&#xff1f; 改变 this 指向没有让函数执行&#xff0c;返回一个改变 this 指向后的函数 bind 难点在于参数的收集 手写 bind 简单实现如下&#xff1a; <script>Function.prototype.kaimoBind function (content) {// 获取到 bind 里的剩余参数let …

「软件设计师」 2023年上半年上午真题解析

「软件设计师」 2023年上半年上午真题解析 提示&#xff1a;系列被面试官问的问题&#xff0c;我自己当时不会&#xff0c;所以下来自己复盘一下&#xff0c;认真学习和总结&#xff0c;以应对未来更多的可能性 关于互联网大厂的笔试面试&#xff0c;都是需要细心准备的 &…