const修饰的成员函数

欢迎来到博主的专栏——C++杂谈
博主ID:代码小豪

文章目录

    • const修饰了什么
    • const修饰的成员函数是为什么?
    • 问答环节

const修饰的成员函数并非是在返回值类型用const,而是在成员函数的末尾加上const,比如:

const char& operator[](size_t pos) const;

我们先忽略这个函数的定义是什么,只需要知道一个事情,这个operator []函数是一个成员函数,并且是一个const修饰的成员函数(只有成员函数才能末尾加上const修饰)。

如果你是一个刚从c语言学完过来学c++的人,如果看到这么一个函数声明,我想大概都是一脸懵逼的,因为这个设定有点反直觉了,在C语言当中,const总是放在函数名或变量名的前面起到修饰作用。

那么为什么c++会有这么一个设计呢?这就不得不提到c++的封装这一特性了。

const修饰了什么

const修饰成员函数到底修饰了什么?它的后面并不存在任何标识符。所以不熟悉c++的人初见这个const当然是一头雾水(博主也是)。

这就得说到c++类的封装特性了。在定义的成员函数当中,该成员函数的实际参数并非我们所声明的那样,比如上例中的operator []成员函数,看起来只声明了一个pos参数。实际上所有的成员函数都有一个隐藏的参数,c++称为this指针。

c++规定,this指针不能显示的声明在成员函数当中。所有的成员函数都会存在一个this指针。虽然this指针不能在参数列表当中声明,但我们可以在函数体内使用this指针。

message& operator =(const message& mes)
{this->_text = mes._text;return *this;
}

this指针是指向调用此函数成员的对象的指针。其类型为object* const this,this指针存在const修饰,因此在成员函数当中对this的指向进行修改是一个非法的操作。

message& operator =(const message& mes){this->_text = mes._text;this = nullptr;//error,this指针不能被修改return *this;}

那么问题来了,虽然我们不能修改this指针,但是可以修改this指针指向的数据(*this)。如果我们声明了一个const类型的对象,那么在这个const对象的this指针就应该是这种类型。const object* const this

在c++中存在权限这一概念,如果一个函数的参数是非const引用或指针类型,那么const的指针或引用参数就不能调用这个函数。我们将其称为c++当中禁止权限的放大

如何理解这个权限的放大呢?我们拿一个例子举例。比如某个函数的参数是非const类型的引用,而实参缺上传了一个const类型,那么这个非const的引用就能对const类型的对象进行修改,这个对象在设计就确定不能被修改,但是通过某个函数缺将该对象修改了,这被称为权限的放大。在c++中是禁止的。

c++允许权限的缩小,禁止权限的放大,一个非const引用不能指向const对象,但是const引用可以指向非const对象

	const int a = 0;int& ra = a;//error,权限的放大。int b = 10;const int& rb = b;//ok,权限的缩小

让我们回到this指针,我们说到非const的对象的this指针的类型是object* const this,而const对象的this指针的类型是const object* const this

而一般的成员函数中的this指针是object* const this,因此一般的成员函数是不能作用与const对象的。因此我们需要将成员函数的隐藏参数this指针的类型修改为const object* const this,但是我们不能再参数列表当中显示的将this指针声明为const object* const this。因此c++允许我们将const放在成员函数的后面,将this指针声明为const object* const this。

	char& operator[](size_t pos)//object*const thisconst char& operator[](size_t pos) const//const object*const this
  • const修饰的成员函数的this指针是const object* const this
  • 非const的成员函数this指针是object* const this

const修饰的成员函数是为什么?

前面已经讲完了const修饰的成员函数,其const修饰的不是函数的返回值,也不是参数列表中的参数。而是成员函数当中的this指针,使其函数能作用于const对象。

那么const修饰成员函数的目的是什么呢?

  • 只有const修饰的成员函数才能作用与const对象身上
  • 能让class接口更加易于理解。函数的使用者可以轻松的得知哪些函数可以改动对象的内容(非const成员函数),哪些函数不会修改对象的内容(const成员函数)。
  • 它们使操作const对象变得灵活(如果一个类定义出来的const对象不能被使用,那么这个类就少了不少的用法)

还有一个很重要的特性。如果两个成员函数是const修饰和非const修饰的,那么这两个函数可以重载。我们看看下面这个类。

class message
{
public:message(const char* str){_text = str;}char& operator[](size_t pos)//object*const this{return _text[pos];}const char& operator[](size_t pos) const//const object*const this{return _text[pos];}private:std::string _text;
};

message的operator []可以被这么使用。

	message text1("hello world");cout << text1[1];//调用的是非const版本的operator []const message text2("hello world");cout << text2[2];//调用的是const版本的operator []

重载operator[]还有一个好处。只要给予operator[]不同的返回类型,就可以让const message对象和非const message对象进行不同的处理。

	message text1("hello world");text1[1] = 'j';//ok,修改了一个char类型的引用cout << text1[1];//ok,返回的是char类型的引用字符const message text2("hello world");text2[2] = 'j';//error,对const char类型的引用进行修改cout << text2[2];//ok,返回的是const char类型的字符

注意,会造成这种差异的原因是operator []的返回类型所致。错误的原因是因为一个对const char&的变量进行赋值操作。

问答环节

问:为什么需要将一个成员函数重载成const版本和非const版本?

答:

  • 这是由于某些成员函数要考虑到const对象和非const对象调用时造成的不同影响。比如非const对象可以被修改,而const对象不可被修改。除外。c++存在这么一个特性:const修饰的成员函数可以接收const类型的对象的this指针和非const类型的对象的this指针,而非const修饰的成员函数不能接收const类型的对象的this指针。(禁止权限的放大)

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

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

相关文章

全网最详细的Python自动化测试(unittest框架)

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

ssm105基于JAVAEE技术校园车辆管理系统+jsp

校园车辆管理系统设计与实现 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本校园车辆管理系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短…

gtest的编译与使用

文章目录 gtest的编译与使用概述笔记CMake参数官方文档测试程序测试效果END gtest的编译与使用 概述 gTest是 googletest的缩写&#xff0c;如果直接找gTest项目&#xff0c;是找不到的。 库地址 https://github.com/google/googletest.git 迁出到本地后&#xff0c;切到最新…

景源畅信数字:抖音小店的入住门槛大不大?

近年来&#xff0c;随着短视频平台的崛起&#xff0c;抖音小店逐渐成为了众多商家和创业者关注的焦点。那么&#xff0c;抖音小店的入住门槛究竟大不大呢?本文将从四个方面对这一问题进行详细阐述。 一、注册流程 抖音小店的注册流程相对简单&#xff0c;只需按照官方指引完成…

HackBar 新手使用教程(入门)

啥是Hackbar&#xff1f; Hackbar是一个Firefox 的插件,它的功能类似于地址栏,但是它里面的数据不受服务器的相应触发的重定向等其它变化的影响。 有网址的载入于访问,联合查询,各种编码,数据加密功能。 这个Hackbar可以帮助你在测试SQL注入,XSS漏洞和网站的安全性,主要是帮助…

揭秘丨文字游侠AI工具:一键生成高质量爆文赚米,提升20倍写作效率,附上渠道和实操教程!

在这个信息泛滥的时代&#xff0c;内容创作者们不断寻求更高效、更创新的方法&#xff0c;以便在众多竞争者中脱颖而出。虽然平台如今日头条为他们提供了展示才华和获取收益的舞台&#xff0c;但如何在激烈的竞争中站稳脚跟&#xff0c;仍是他们需要面对的挑战。然而&#xff0…

​Inf-DiT:Upsampling Any-Resolution Image、Vidu、MVDiff、Trio-ViT

本文首发于公众号&#xff1a;机器感知 ​Inf-DiT&#xff1a;Upsampling Any-Resolution Image、Vidu、MVDiff、Trio-ViT Inf-DiT: Upsampling Any-Resolution Image with Memory-Efficient Diffusion Transformer Diffusion models have shown remarkable performance in im…

力扣题目101:对称二叉树

作者介绍&#xff1a;10年大厂数据\经营分析经验&#xff0c;现任大厂数据部门负责人。 会一些的技术&#xff1a;数据分析、算法、SQL、大数据相关、python 欢迎加入社区&#xff1a;码上找工作 作者专栏每日更新&#xff1a; LeetCode解锁1000题: 打怪升级之旅 python数据分析…

js原生手写一个拖拽小功能

先上效果图 附上代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta http-equiv"X-UA-Compatible" content"IEedge" /><meta name"viewport" content"widthd…

Python自动化测试五大框架(测试员收藏夹必备)

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

Java 语法 (杂七杂八的知识)

面向对象三大特性 封装, 多态, 继承 基本数据类型 一字节 (Byte) 占八位 (bit) JDK, JRE, JVM JDK (Java Development Kit) : Java 开发工具包, 包括了 JRE, 编译器 javac, 和调试工具 Jconsole, jstack 等 JRE (Java Runtime Environment) : Java 运行时环境, 包括了 JVM , …

基于Vue3与ElementUI Plus的酷企秀场景可视化DIY设计器:前端技术引领下的数字化展示新篇章

一、引言 在当今信息化高速发展的时代&#xff0c;企业对于展示自身形象、提升用户体验以及增强品牌知名度的需求日益迫切。针对这一市场需求&#xff0c;我们推出了基于Vue3与ElementUI Plus的酷企秀场景可视化DIY设计器。该产品不仅具备电子画册、VR全景、地图秀三大核心功能…

Java小白_面向对象程序设计01顺序结构_01Java顺序结构之数学函数之根据三角形三边长求面积

练习 -Java顺序结构之数学函数之根据三角形三边长求面积 Java顺序结构之数学函数之根据三角形三边长求面积 练习 -Java顺序结构之数学函数之根据三角形三边长求面积1. 任务要求任务描述编程要求测试说明 2. 任务分析1. 输入输出分析2. 需求分析3. 所需知识1. java 库 如何获取输…

Docker-compose部署Fastapi项目

Docker-compose部署Fastapi、postgres、Redis、Nginx) 之前有写过使用容器部署的方式&#xff0c;这次尝试使用Docker-compose试一次大胆的尝试 使用容器的方式部署只是掌握这项技能的基础&#xff0c;在使用Docker-compose的过程中会有些稍许的不同。毕竟踩过的坑才算是跨过去…

如何在PPT中插入网页?这样操作,免费还高效!

融合课、跨学科课&#xff0c;已经是近两年来教育界的热门词。 在公开课、微课比赛中&#xff0c;不添融合一些较为先进的信息技术&#xff0c;都不好意思拿出手了。 最近&#xff0c;由不坑老师开发制作的Office插件——不坑盒子&#xff0c;实现了在PPT中插入网页&#xff…

ARM(4)缓存一致性

目录 一、缓存一致性问题 二、一致性实现方案 2.1 目录一致性协议 2.2 嗅探一致性协议 三、CHI协议 3.1 cache state 3.2 snoop维护一致性 四、其他一致性协议 4.1 MSI协议 4.2 MESI 协议 4.3 MOESI协议 本文介绍以下内容&#xff1a; 缓存一致性问题一致性实现方案…

从原始边列表到邻接矩阵Python实现图数据处理的完整指南

​​本文分享自华为云社区《从原始边列表到邻接矩阵Python实现图数据处理的完整指南》&#xff0c;作者&#xff1a; 柠檬味拥抱。 在图论和网络分析中&#xff0c;图是一种非常重要的数据结构&#xff0c;它由节点&#xff08;或顶点&#xff09;和连接这些节点的边组成。在Py…

设计模式之前端控制器模式

想象一下&#xff0c;你的Java Web应用是个交响乐团&#xff0c;每个功能模块是乐手&#xff0c;而用户请求就像是一首首待演绎的曲目。在这场音乐盛宴中&#xff0c;谁来保证演出的流畅与协调&#xff1f;答案就是——前端控制器模式&#xff01;它如同乐队的指挥&#xff0c;…

java中如何判断一个数是不是素数(质数)

相关概念 质数就是大于1的自然数字中&#xff0c;只能被1和它自己整除的数。 题目 求101~200之间的质素的个数 代码实现 判断一个数是不是质数 for (int j 2; j < i; j) {if(i % j 0){flag false;break;}}if(flag){System.out.println("当前数字是质数");…

【动态规划】:路径问题_地下城游戏

朋友们、伙计们&#xff0c;我们又见面了&#xff0c;本专栏是关于各种算法的解析&#xff0c;如果看完之后对你有一定的启发&#xff0c;那么请留下你的三连&#xff0c;祝大家心想事成&#xff01; C 语 言 专 栏&#xff1a;C语言&#xff1a;从入门到精通 数据结构专栏&…