C++技能系列 ( 2 ) - const的几种使用【详解】

news2024/11/17 11:00:44

系列文章目录

C++高性能优化编程系列
深入理解软件架构设计系列
高级C++并发线程编程
C++技能系列

期待你的关注哦!!!
在这里插入图片描述

生活就是上帝发给你的一张手牌,无论多烂,你都得拿着。
Life is god give you a hand, no matter how bad, you have to take.

const的几种使用

  • 系列文章目录
  • 一、声明带const
    • 1、const int a
    • 2、const int &a
    • 3、const char *p & char const *p
    • 4、char * const p
    • 5、const char * const p & char const * const p
  • 二、函数形参带const
    • 1、函数形参带const的 - 使用
    • 2、函数形参带const的 - 好处
  • 三、成员函数末尾带const
  • 四、const的克星mutable
  • 五、小结

一、声明带const

1、const int a

(1)表示常量a,不能改变a的值

//不能改变p的值
const char p = 'f';

2、const int &a

(1)表示常量引用,a代表的内容不能修改

int i = 100const int &a = i; //表示a所代表的内容不能被修改
const int &b = 156;  //可以,字面值初始化常量引用
int &c = 156; //错误
b = 157; //错误,b看成常量,值不能修改

3、const char *p & char const *p

(1)'char const *p;'等价于'const char *p;'
(2)表示常量指针(p所指向的内容不能通过p来修改):

char str[] = "I Love China";
char *p;
p = str;
*p = 'Y';
p++; //p可以指向不同的位置,只要这些位置的内存归我们管即可

如果将p的定义修改为:

const char *p; //表示常量指针(p所指向的内容不能通过p来修改)
*p = 'Y'; //错误

当然,通过str修改内容则没有问题:

str[0] = 'Y';

4、char * const p

(1)表示指针常量(p不可以指向其他内容):

看如下范例:

char str[] = "I Love China";
char * const p = str;  //定义的时候必须初始化
p++;   //这里不可以,p指向一个内容后,不可以指向其他内容(p不可以指向不同目标)
*p = 'Y';  //但可以修改指向的目标的内容

5、const char * const p & char const * const p

(1)'const char * const p;'等价于'char const * const p;'
(2)表示p的指向不能改变,p指向的内容也不能通过p来改变。

二、函数形参带const

1、函数形参带const的 - 使用

struct student {int num};
void fs(student &stu){
	stu.num = 1010;
}
student abc;
abc.num = 100;
fs(abc);
std::cout << abc.num << std::endl; //1010

上面这段代码,可以注意到,在fs()函数中可以修改stu里的num成员,修改后,该值会被带回到主调函数中,也就是说,fs()函数中对形参stu的修改实际就是对实参abc的修改,因为这里形参采用的是引用类型。

如果不希望在函数fs中修改形参stu里的值,建议形参最好使用常量引用的习惯。

void fs(const student &stu){
	stu.num = 1010;  //这句就错误了,不能修改stu中的内容
}

再继续看范例:

void fs(const int i){ //实参可以是正常的int,形参可以使用const int接,这都没问题
	i = 100;   //这也不行,不能给常量赋值
}

2、函数形参带const的 - 好处

(1)可以防止无意中修改了形参值导致实参值被无意中修改掉。
(2)实参类型可以更加灵活。

struct student {int num};
void fs(student &stu){
	
}
student abc;
abc.num = 100;
const student& def = abc;
fs(def);//错误,因为def类型是const&,而函数fs的形参不带const
std::cout << abc.num << std::endl; //1010

如果改成:

void fs(const student &stu){
	
}

可以看到const student &stu这种类型的形参可以接受的实参类型更多样化,可以接收普通的引用作为实参,也可以接收常量引用作为实参。

再继续看看如下范例:

void func2(int &a);//定义函数func2()
func2(156);//不可以,必须传递进去一个变量

修改后:

void func2(const int &a);//定义函数func2()
func2(156);//可以,可以船进去一个常量

三、成员函数末尾带const

成员函数末尾加const起什么作用呢?表示该成员函数不会修改该对象里面的任何成员变量的值。

这种在末尾加了一个const的成员函数也称常量成员函数。

class Persion{
public:
	void Get() const{
		a_ += 10;   //错误,常量成员函数不可以修改成员变量的值
	}
	void Add(int x){
		a_ = a_ - x ;
	}
private:
	int a_;
}

从上面的代码看,如果在Get的成员函数中修改成员变量a_的值,是不被允许的。

看看如下范例:

//	定义const对象,这种对象有限制
const Persion per;
//	不可以,Add成员函数是非const的,只能被非const的对象调用
per.Add(14);
// 可以因为Get()的成员函数是const
per.Get();
Persion per2;
//Get是const成员函数,则不管是cosnt对象还是非const对象都可以调用const员函数
//而非const得成员函数不能被const对象调用,只能被非const对象调用
per2.Add();

总结一下:

(1)const成员函数,则不管是cosnt对象还是非const对象都可以调用const员函数。
(2)而非const得成员函数不能被const对象调用,只能被非const对象调用。
(3)普通函数(非成员函数)末尾是不能加const, 编译都无法通过。

四、const的克星mutable

mutable,翻译成中文不稳定的、容易改变的意思。与const正好是反义词。而且mutable的引入也正是为了突破const的限制。

刚刚已经看到,在末尾有const修饰的成员函数中,是不允许修改成员变量值的。那在设计类成员变量的时候,假如确实遇到了需要在const结尾的成员函数中希望修改成员变量值的需求,怎么办呢?

也许有人会说,那就把函数末尾的const去掉,变成一个非const的成员函数。那就会引入一个新问题,如果这个成员函数从const变成一个非const的了,那么就不能被const对象调用。

所以,引入了mutable修饰符(关键字)来修饰一个成员变量。一个成员变量一旦被mutable所修饰,就表示这个成员变量永远处于可变的状态,即使在以const结尾的成员函数中。

看如下范例:

class Persion{
public:
	void Get() const{
		a_ += 10;  //可以修改成员变量a_了
	}
	void Add(int x){
		a_ = a_ - x ;
	}
private:
	mutable int a_;
}

五、小结

开发中经常使用,面试中也是经常被问的,所以谨记于心。

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

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

相关文章

【前端面试手册】CSS系列-01

本专栏收录于《前端面试手册-CSS篇》如果该文章对您有帮助还希望你能点一个小小的订阅&#xff0c;来增加博主创作的动力✍&#x1f3fb; 一、什么是盒子模型&#xff0c;说说你的理解&#xff1f; 首先&#xff0c;如果你要对一个文档进行布局的时候&#xff0c;浏览器的渲染…

[进阶]Java:对象序列化、反序列化

对象序列化&#xff1a; 使用到的流是对象字节输出流&#xff1a;ObjectOutputStream作用&#xff1a;以内存为基础&#xff0c;把内存中的对象存储到磁盘文件中去。称为对象序列化。 代码演示如下&#xff1a; 学生类&#xff1a; /**对象如果要序列化一定要实现Serializab…

力扣题库刷题笔记7--N字型变换

1、题目如下&#xff1a; 2、个人Python代码实现&#xff1a; 看到此题的第一反应就是&#xff0c;生成一个类似二维数组的多个字符串&#xff0c;然后用个标志位控制N字符中字符的方向&#xff0c;例如flag True&#xff0c;在每次循环时候以flag flag * -1来控制。 由于示例…

Oracle-ASM磁盘组HIGH模式丢盘问题处理

背景: 用户一套Oracle19c的RAC集群ASM磁盘组使用了3个存储作为HIGH以及NORMAL冗余模式&#xff0c;每个存储分别对应一个failgroup&#xff0c;其中2个存储出现了故障导致ASM磁盘组对应的failgroup磁盘全部offline&#xff0c;在存储恢复正常之后&#xff0c;需要将offline的磁…

2020年全国硕士研究生入学统一考试管理类专业学位联考英语(二)试题

2020年英语二联考真题 一、完形填空 Directions: Read the following text. Choose the best word for each numbered blank and mark A, B, C or D on the ANSWER SHEET (10 points) Being a good parent is what every parent would like to be. But defining what it mea…

《Java黑皮书基础篇第10版》 第17章【习题】

Java语言程序设计 习题第十七章 17.2章节习题 17.1什么是文本文件&#xff0c;什么是二进制文件&#xff1f;可以使用文本编辑器来查看文本文件或者二进制文件吗&#xff1f; 文本文件是字符组成的文件&#xff0c;二进制文件是0和1组成的文件 文本编辑器只能访问文本文件 17…

一文教你彻底学会SPI协议

一文教你彻底学会IIC协议 一.概况SPI二.SPI连接2.1 一主一从2.2 一主多从 三.SPI通信过程3.1 CPOL&#xff08;极性&#xff09;和CPHA&#xff08;相位&#xff09;3.2 SPI时序图3.1 SPI起始信号3.2 SPI停止信号3.3 数据的有效性 四.代码实例 一.概况SPI SPI 协议是由摩托罗拉…

腾讯云服务器开Minecraft配置怎么选择?

腾讯云服务器Minecraft我的世界服务器配置怎么选择&#xff1f;10人以内玩2核4G就够用了&#xff0c;腾讯云开我的世界服务器选择轻量应用服务器就够了&#xff0c;轻量CPU采用至强白金处理器&#xff0c;大型整合包一般1.12版本的&#xff0c;轻量2核4G配置都差不多的&#xf…

智慧加油站卸油作业行为分析算法 opencv

智慧加油站卸油作业行为分析系统通过opencvpython网络模型技术&#xff0c;智慧加油站卸油作业行为分析算法实现对卸油作业过程的实时监测。当现场出现卸油作业时人员离岗&#xff0c;打电话人员抽烟等违规行为&#xff0c;灭火器未正确摆放&#xff0c;明火和烟雾等异常状态&a…

VMware 逃逸基础知识

虚拟化相关概念 VMM&#xff1a;即 VM Monitor &#xff0c;也被称为 Hypervisor&#xff08;虚拟机监控程序&#xff09;。VMM 是 guest os 的管理器&#xff0c;管理虚拟机运行。例如 Windows 的 Hyper-V &#xff0c;linux 的 KVM 以及裸机上安装的 Xen 和 VMware ESXi 都属…

《MySQL是怎么运行的》阅读笔记

mysql运行的整体架构简介 Mysql是由两部分构成&#xff0c;一部分是服务器程序&#xff0c;一部分是客户端程序。 服务器程序又包括两部分&#xff1a; 第一部分server层包括连接器、查询缓存、分析器、优化器、执行器等。涵盖 MySQL 的大多数核心服务功能&#xff0c;以及所有…

【Android复习笔记】Glide核心原理

Glide 核心流程 Glide中RequestManager会管理两个队列,一个请求队列,一个等待队列,当生命周期onStop停止时,把运行队列中的任务添加到等待队列中,当生命周期onResume恢复时,又从等待队列中添加到运行队列执行。 关于 Glide.with(this).load(url).into(iv); 主要搞清楚三…

Doris初认识

Doris初认识 文章目录 Doris初认识1. Doris 概述2. 核心特性3. 使用场景4. 架构 1. Doris 概述 Apache Doris 是由百度大数据部研发&#xff08;之前叫百度 Palo&#xff0c;2018 年贡献到 Apache 社区后&#xff0c;更名为 Doris &#xff09;&#xff0c;在百度内部&#xff…

Schneider Electric EcoStruxure Control Expert 15.3 Crack

Schneider Electric EcoStruxure Control Expert 15.3专为使用施耐德电气的Modicon PLC&#xff08;可编程逻辑控制器&#xff09;的控制和自动化工程师量身定制。它提供了一系列功能和工具&#xff0c;以方便自动化应用程序的开发、部署和维护。 施耐德电气EcoStruxure控制专家…

优化命令测试

命令内容&#xff1a; nload、free 目录 一、nload 1.删除yum仓库本地源 local.repo 2.nload命令的环境依赖文件只有在epel商城才有 所以需要安装epel 3.压力测试 二、free 1.free功能 2.free参数​编辑 4.实验&#xff1a;使用压力测试工具dd 查看内存使用的变化 总…

KUKA机器人出现“如果文件以写入方式打开,则不允许选择或执行程序”的解决办法

KUKA机器人出现“如果文件以写入方式打开,则不允许选择或执行程序”的解决办法 情景再现: 在操作KUKA机器人时可能会遇到这样的情况:如下图所示,即操作人员登录了管理员权限后,打开了config配置文件, 正常情况下,应该像下图所示点击左侧的来关闭config配置文件,但是…

Java012——引用数据类型String的简单学习

回顾Java数据类型 本次要学习的是Java引用数据类型String 一、对String类简单说明 说明&#xff1a;String是Java中的一个类 二、String类的作用 作用&#xff1a;主要用来创建和操作字符串。 三、使用String类 3.1、创建字符串 注意&#xff1a; 1、字符串使用双引号&qu…

【SQL应知应会】分析函数的点点滴滴(二)

欢迎来到爱书不爱输的程序猿的博客, 本博客致力于知识分享&#xff0c;与更多的人进行学习交流 本文收录于SQL应知应会专栏,本专栏主要用于记录对于数据库的一些学习&#xff0c;有基础也有进阶&#xff0c;有MySQL也有Oracle 分析函数的点点滴滴 1.什么是分析函数&#xff1a;…

Linux中新建用户使用sudo问题

文章目录 sudo问题 sudo问题 sudo&#xff1a;权限提示指令&#xff0c;当使用sudo这条指令时&#xff0c;会将普通用户的权限提升为root权限 但是在命令行新建用户&#xff0c;这个用户使用sudo指令对一条指令提权是用不了的 这个用户没有在sudoers file这个文件中&#xff…

读发布!设计与部署稳定的分布式系统(第2版)笔记05_层叠

1. 水平扩展 1.1. 增加服务器来增加容量 1.1.1. 这些服务器集群被称为“农场” 1.2. 负载均衡的服务器集群 1.2.1. 不易遭遇单点系统失效 1.2.2. 高负载比低负载更易导致竞态条件的并发缺陷 1.3. 如果双节点集群出现失效&#xff0c;那么幸存服务器的工作负载将增加一倍 …