C++技能 - 详解const的几种使用【再也不迷糊了,干货还是蛮多的】

news2024/10/6 19:06:20

系列文章目录

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/635581.html

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

相关文章

RK3588平台开发系列讲解(以太网篇)MDIO底层驱动

平台内核版本安卓版本RK3588Linux 5.10Android 12文章目录 一、mdiobus总线二、mdiobus的注册沉淀、分享、成长,让自己和他人都能有所收获!😄 一、mdiobus总线 mdio bus是mdio管里phy寄存器的总线,此总线非设备驱动模型之总线。mdiobus在内核中用mii_bus结构体描述,mii_b…

基于51单片机的电子钟Protues仿真设计

一、设计背景 电子钟是指利用数字电路或单片机等现代电子技术来实现时间计量和显示的钟表。相较于传统机械钟、石英钟等时钟&#xff0c;电子钟具有精度高、音响小、易于制造和调节等优点&#xff0c;同时也由于其美观大方的外观设计而成为了家居装饰中不可或缺的一部分。 其…

初探react中使用MongoDB

MongoDB介绍与安装 什么是MongoDB 来自于英文单词“Humongous”&#xff0c;中文含义表示“庞大”面向文档存储的开源数据库由C编写&#xff0c;支持多种语言连接 为什么要用MongoDB 性能好&#xff08;内存计算&#xff09;大规模数据存储&#xff08;可拓展性&#xff09…

Cracking C++(9): 编译选项的设置

文章目录 1. 目的2. 生成 hello 可执行程序的过程3. 编译选项4. overlook 项目简介4.1 基本用法4.2 典型例子&#xff1a; 函数缺少返回值 1. 目的 对应到 hackingcpp 网站上 Hello World 这一节内容的笔记和个人的拓展。 2. 生成 hello 可执行程序的过程 #include <iost…

牛客网专项练习——C语言错题集(3)

文章目录 函数的缺省返回值类型找不同数组指针 函数指针const 与 指针函数里操作外面传进来的数组 函数的缺省返回值类型 “在C语言中&#xff0c;凡不加返回值类型限定的函数&#xff0c;就会被编译器作为返回整型值处理。” 这是初学学 C 语言时有接触到的一个概念&#xf…

RK3588平台开发系列讲解(进程篇)进程task_struct结构体详解(一)

平台内核版本安卓版本RK3588Linux 5.10Android 12文章目录 一、任务 ID二、信号处理三、任务状态四、进程调度沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 Linux 里面,无论是进程,还是线程,到了内核里面,我们统一都叫任务(Task),由一个统一的结构 task_stru…

1.uniapp可视化操作-diygw

DAY1-uniapp可视化操作:DIY可视化-拖拽设计1天搞定主流小程序环境安装 文章目录 DAY1-uniapp可视化操作:DIY可视化-拖拽设计1天搞定主流小程序环境安装前言一、DIY可视化桌面客户端安装:二、小皮管理面板phpstudy(或者宝塔桌面)三、phpstorm开发工具:四、Vs Code安装:五、hbuil…

《Java Web轻量级整合开发入门》学习笔记

轻量级Java Web整合开发 第一章 轻量级Java Web开发概述 1.2 java web 开发概述 1.JSP是一种编译执行的前台页面技术。对于每个JSP页面&#xff0c;Web服务器都会生成一个相应的Java文件&#xff0c;然后再编译该Java文件&#xff0c;生成相应的Class类型文件。在客户端访问到…

chatgpt赋能python:Python怎么合并字典

Python怎么合并字典 在Python编程中&#xff0c;字典是一种非常有用的数据结构。它由一组键值对组成&#xff0c;每个键值对都是一个键和对应的值。有时候&#xff0c;我们需要将两个或多个字典合并为一个大的字典。本文将介绍Python中合并字典的方法。 方法一&#xff1a;使…

[架构之路-212]- 需求- UML需求建模:用例图、ER图/概念类图、流程图、序列图、状态机图

目录 前言&#xff1a; 什么是需求建模 1. 用例图 1.1 用例图 1.1.1 组件 1.1.2 用例细化与用例关系 1.2 用例规约 2. ER图/概念类图 3. 跨角色流程图&#xff08;串行、协同&#xff09; 4. 活动图&#xff08;并行、协同&#xff09; 5. 状态机图 6. 时序图 前言…

Letcode经典黄题——三数之和

还是那句话&#xff0c;一个题思路很重要&#xff0c;没有思路等于无头苍蝇乱撞 题目要求&#xff1a;给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 …

chatgpt赋能python:Python怎么变黑?探索Python黑科技的奥秘

Python怎么变黑&#xff1f;探索Python黑科技的奥秘 如果你在网上搜索“Python怎么变黑”&#xff0c;你会看到很多关于Python黑客技术的讨论。但是&#xff0c;这篇文章将会聚焦于Python如何变得更“黑”&#xff0c;即在SEO优化方面如何利用Python。 Python在SEO优化中的作…

华硕天选4原装Windows11系统带ASUSRECOVERY恢复工厂模式安装

华硕工厂恢复系统 &#xff0c;安装结束后带隐藏分区以及机器所有驱动软件,奥创Myasus Recovery 文件地址https://pan.baidu.com/s/1Pq09oDzmFI6hXVdf8Vqjqw?pwd3fs8 提取码:3fs8 文件格式&#xff1a;5个底包(HDI KIT COM MCAFEE EDN) 1个引导工具TLK 支持ASUSRECOVERY型…

chatgpt赋能python:Python和Envi:完美结合的最佳方案

Python和Envi&#xff1a;完美结合的最佳方案 如果你正在寻找一种可靠的方法来将Python编程与Envi软件结合起来&#xff0c;那么你来对地方了&#xff01;在本篇文章中&#xff0c;我们将介绍如何使用Python编程语言和Envi软件相互结合&#xff0c;从而让你的数据分析和地理信…

价值8k的电子书小程序源码+前端(含教程)

&#x1f388; 限时活动领体验会员&#xff1a;可下载程序网创项目短视频素材 &#x1f388; &#x1f389; 有需要的朋友记得关赞评&#xff0c;阅读文章底部来交流&#xff01;&#xff01;&#xff01; &#x1f389; ✨ 源码介绍 价值8k的电子书小程序源码_附完整教程 无意…

chatgpt赋能python:Python的字符串处理功能:取出字符串的每一位

Python的字符串处理功能&#xff1a;取出字符串的每一位 Python是广泛应用于Web开发、数据分析、机器学习、人工智能和爬虫等领域的一门程序语言。其中&#xff0c;字符串是Python最常见的数据类型之一&#xff0c;也是Web开发中交互数据的主要形式。在Python中&#xff0c;字…

UDS关于0x34服务请求下载学习

1.服务介绍 客户端使用requestDownload服务启动从客户端到服务器的数据传输&#xff08;下载&#xff09;。在服务器收到requestDownload请求消息后&#xff0c;服务器应采取一切必要措施接收数据&#xff0c;然后再发送肯定响应消息。 2.请求消息 2.1请求消息定义 C1&#x…

javaSE -- 注解学习笔记

参考资料&#xff1a;https://blog.csdn.net/KingBoyWorld/article/details/105337011 https://blog.csdn.net/qq_42843172/article/details/107293408 1.注解是什么&#xff1f; java注解是一个写在接口、类、属性方法上的一个标签。跟注释不同&#xff0c;能够影响代码。 …

算法模板(5):数学(1):数学知识(1)

数论 整数的整除性 [x]表示不超过x的最大整数&#xff0c;叫做取整函数或高斯函数。设整数a&#xff0c;b不同时为零&#xff0c;则存在一对整数m&#xff0c;n&#xff0c;使得 ( a , b ) a m b n (a, b) am bn (a,b)ambn。注&#xff1a;a和b的最大公因数会写成 (a, b)…

vue3中使用Vuex

目录 什么是Vuex安装和配置Vuex安装Vuex配置Vuex 使用VuexState定义State访问State MutationsMutations 的特点定义Mutations触发Mutations 修改State中的状态 ActionAction 的特点和作用定义Action触发Action GetterGetter 的特点和作用定义Getter获取Getter ModuleModule 的特…