C++对const引用的特殊处理、为什么函数形参的引用建议加上const?只是为了防止值被修改吗?

news2024/11/17 3:52:16

前言:我们知道普通变量、指针、函数形参,加上const修饰表示不可改变,但是引用前面加上const就有特别之处了

目录

const日常使用

const引用的特别处理

        const引用创建临时变量规则

引用形参声明为const的三个理由


const日常使用

我们知道如果我们想修改函数传入的实参的值,我们就必须传地址,也就说值传递,值传递有两种方式,一是传引用,而是传指针;

先看示例代码:

#include <iostream>
using namespace std;

// 传指针
void PModify(int* age, string* name)
{
	*age = 20;
	*name = "指针法";
	cout << "指针法函数内部输出:" << *age << " " << *name << endl;
}

// 传引用
void CModify(int& age, string& name)
{
	age = 33;
	name = "引用法";
	cout << "引用法函数内部输出:" << age << " " << name << endl;
}

int main()
{
	// 写一个函数修改下面两个变量的值
	int age = 10;
	string name = "赵四";

	PModify(&age, &name);

	cout << "修改后:" << age << " " << name << endl;

	cout << endl;

	CModify(age, name);

	cout << "修改后:" << age << " " << name << endl;

	return 0;
}

运行:

 

没有问题,引用法和指针法都正确的修改了变量的值;

下面我们把形参全部都加上const:

出错了,const形参不能被修改内容;这也是const引用的用途之一:防止实参被修改 

但是,const引用还有一个很特别的用途,下面为大家介绍

const引用的特别处理

先把代码写成这样:

#include <iostream>
using namespace std;

// 传指针
void PModify(int* age, string* name)
{
	cout << "指针法函数内部输出:" << *age << " " << *name << endl;
}

// 传引用
void CModify(int& age, string& name)
{
	cout << "引用法函数内部输出:" << age << " " << name << endl;
}

int main()
{
	// 写一个函数修改下面两个变量的值
	int age = 10;
	string name = "赵四";

	PModify(&age, &name);

	CModify(age, name);

	return 0;
}

const全部去掉,主函数就调用这两个输出函数就行了,另外注意,这个时候主函数调用PModify和CModify的时候,传入的实参是变量;

运行一下:

正常输出没有问题;

那么我们如果实参传入常量呢?字面量?如下:

 

编译不通过,因为他需要的是一个地址,我们这里传了一个常量,肯定不行啊;

那么形参是引用的函数可以吗?(盲猜一下不可以):

 

也不行;

我这里先展示解决方法,再为大家讲解为什么;

我们只需要在引用形参前面加上const,那么就可以传入常量了,如下:

那么指针也有这种待遇吗?

 

还是不行,这是为什么呢?

因为C++对引用的const做了优化,他会创建临时变量,让引用指向临时变量;

        const引用创建临时变量规则

什么时候将会创建临时变量呢?

1、引用为const

2、数据对象的类型是正确的,但不是左值

3、数据对象的类型不正确,但是可以转换为正确的类型

我们先来讲一下什么是左值,什么是右值:

左值是可以被引用的数据对象,可以通过地址访问他们,例如:变量、数据元素、结构体成员、引用和解引用的指针;

右值包括字面常量(用双引号包含的字符串除外)和包含多项的表达式

首先第一点引用为const这是必须的,也不需要证明;

再看第二点

怎么理解这句话呢?下面我为大家举个栗子:

看过我之前的文章《引用和指针》的小伙伴应该知道,引用的本质也是取地址,那么这个常量(右值)8我们可以取地址吗?

不可以;所以编译未通过啊;

那么我们加上const呢?

编译通过了,是因为加上const之后,常量(右值)8就是个地址或者是就是个左值了吗?

不是的 

是因为满足了条件2,成功的触发了创建临时变量的功能!

就是这个道理,类型匹配的但不是左值的时候,如果我们的引用是const,那么他就会创建临时变量;

他的本质和下面两行代码没有区别:

红框1==红框2;

再看第三点:数据对象的类型不正确,但是可以转换为正确的类型;

先看代码:

#include <iostream>
using namespace std;

// 传指针
void PModify(const int* age, const string* name)
{
	cout << "指针法函数内部输出:" << *age << " " << *name << endl;
}

// 传引用
void CModify(const int& age, const string& name)
{
	cout << "引用法函数内部输出:" << age << " " << name << endl;
}

int main()
{
	CModify(18, "赵四");

	return 0;
}

运行:

没有问题,正确输出;

上面说的是类型不匹配,但是可以转为正确的类型,那么我们改改:

 

这下类型不匹配了,再次运行:

 

成功输出!

我们把const去掉会怎么样呢?这里我全部去掉,大家自己可以尝试,去掉哪一个都会报错:

 

去掉const报错了,加上const就成功输出,这说明const有在为'X'和"赵四"创建临时变量; 

可能有人会问,这个测试哪里满足了观点3?

观点3:类型不匹配,可以转换为正确的类型

测试里:

'X'是字符,和int不匹配吧,但是我们都知道,字符实质上就是整数,所以可以转换为正确的类型没有问题吧;

"赵四"的类型是const char*,string的本质也是一个char*的容器,所以"赵四"也能正确的转换为string类型;

这两个参数都满足观点3,所以形参引用加上const就会创建临时变量,程序运行也就不会有问题;

引用形参声明为const的三个理由

1、使用const引用可以避免无意中修改数据的编程错误;

2、使用const引用使函数能够处理const和非const实参,否则只能接收非const实参;

3、使用const引用函数能正确生成并使用临时变量;

以上便是文章的全部内容,感谢观看!

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

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

相关文章

resnet(2)------看看卷积

文章目录1 . 人脑是怎么认识到物体的2. 卷积3. 卷积核1 . 人脑是怎么认识到物体的 在谈卷积之前&#xff0c;我们先来了解一下人是怎么认识物体的。 人脑是个非常复杂的结构&#xff0c;是由无数个神经元连接起来&#xff0c;每个神经元都有自己负责记忆的东西。当人眼看到物体…

关于自增约束auto_increment需要注意的地方,mysql8版本的报错

目录一&#xff0c;自增约束auto_increment需要注意的地方附&#xff1a;就算插入数据失败&#xff0c;也进行自增&#xff1a;二&#xff0c;自增约束auto_increment在MySQL8版本的报错&#xff1a;一&#xff0c;自增约束auto_increment需要注意的地方 1 创建数据库表class&…

Logistic回归

通常&#xff0c;Logistic回归用于二分类问题&#xff0c;例如预测明天是否会下雨。当然它也可以用于多分类问题. Logistic回归是分类方法&#xff0c;它利用的是Sigmoid函数阈值在[0,1]这个特性。Logistic回归进行分类的主要思想是&#xff1a;根据现有数据对分类边界线建立回…

啊?我这手速也太差了吧?——C++Easyx“挑战六秒”小游戏

&#x1f411;本文作者&#xff1a;C橙羊&#x1f411; &#x1f3ae;&#x1f50a;本文代码适合编译环境&#xff1a;DEV-C&#x1f4bb; ✨&#x1f9e8;温馨提示&#xff1a;此文转载于codebus&#x1f389;&#x1f3a0; 最近橙羊在Easyx官网的codebus里随便逛逛的时候&am…

SpringMVC从入门到精通(一)

文章目录1. SpringMVC基本概念1.1 三层架构1.2 MVC架构1.3 什么是SpringMVC1.4 SpringMVC的优势2. SpringMVC 的入门2.1 入门程序2.2 SpringMVC执行原理刨析2.3 SpringMVC的核心执行流程2.4 SpringMVC的组件3. RequestMapping注解4.请求参数绑定4.1 参数绑定4.2 请求参数乱码问…

磨金石摄影技能干货分享|优秀纪实摄影作品欣赏—北京记事

1、蜂窝煤 三名青年男子踏着三轮车拉着满满一车蜂窝煤。脸上流露出清澈的笑容。这是九十年代的北京&#xff0c;背后的天安门格外的显眼。那时候处于改革开放的初期&#xff0c;虽然还不是很富裕&#xff0c;但大家脸上洋溢着幸福与希望的笑容。 蜂窝煤是冬天必备&#xff0c;九…

【强化学习论文合集】十一.2018国际表征学习大会论文(ICLR2018)

强化学习(Reinforcement Learning, RL),又称再励学习、评价学习或增强学习,是机器学习的范式和方法论之一,用于描述和解决智能体(agent)在与环境的交互过程中通过学习策略以达成回报最大化或实现特定目标的问题。 本专栏整理了近几年国际顶级会议中,涉及强化学习(Rein…

历届青少年蓝桥杯python编程选拔赛 STEMA评测比赛真题解析【持续更新 已更新至34题】

蓝桥杯python选拔赛真题 历届青少年蓝桥杯python编程选拔赛真题解析 选拔赛 真题34-回文数升级 【蓝桥杯选拔赛真题34】python回文数升级 青少年组蓝桥杯python 选拔赛STEMA比赛真题解析_小兔子编程的博客-CSDN博客python回文数升级2020年青少年组python蓝桥杯选拔赛真题一、…

剑指Offer39——数组中出现次数超过一半的数字

摘要 剑指Offer39 数组中出现次数超过一半的数字 本题常见的三种解法&#xff1a; 哈希表统计法&#xff1a; 遍历数组 nums &#xff0c;用 HashMap 统计各数字的数量&#xff0c;即可找出 众数 。此方法时间和空间复杂度均为 O(N) 。数组排序法&#xff1a; 将数组 nums 排…

Python学习-8.1.1 标准库(time库的基础与实例)

2.1 time库 time库是Python提供的处理时间标准库。time库提供系统级精确计时器的计时功能&#xff0c;可以用来分析程序性能&#xff0c;也可以让程序暂停运行时间。 2.1.1 时间处理函数 time.time()函数&#xff1a;获取当前时间戳。 代表着如今的时间与1970年1月1日0分0秒…

18.10 字节码指令集与解析举例 - 同步控制指令

同步控制指令 组成 java虚拟机支持两种同步结构&#xff1a;方法级的同步和方法内部一段指令序列的同步&#xff0c;这两种同步都是使用monitor来支持的。 方法级的同步 方法级的同步&#xff1a;是隐式的&#xff0c;即无须通过字节码指令来控制&#xff0c;它实现在方法调…

Java+SSM网上书城全套含微信支付电商购物(含源码+论文+答辩PPT等)

项目功能简介: 本项目含代码详细讲解视频&#xff0c;手把手带同学们敲代码从0到1完成项目 该项目采用技术Springmvc、Spring、MyBatis、Tomcat服务器、MySQL数据库 项目含有源码、配套开发软件、软件安装教程、项目发布教程以及代码讲解教程 项目功能介绍&#xff1a; 系统管理…

HTML做一个简单的页面(纯html代码)地球专题学习网站

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

STM32F4 | 新建工程模板——寄存器版本 | HAL库入门 | 新建工程模板——库函数版本

文章目录一、新建工程模板——寄存器版本二、HAL入门1.固件库和寄存器的区别2.STM32CubeF43.HAL库包介绍三、新建HAL库工程模板一、新建工程模板——寄存器版本 开发环境&#xff1a;MDK5软件包&#xff1a;STM32CubeF4包 新建工程模板的一般步骤为&#xff1a; 新建工程目录&a…

【UE5】多用户协同编辑

UE5新出了一个多用户协同功能所以想搭一个来玩玩。 Epic已经将流程极度的简化了&#xff0c;在B站虚幻官方也放出了教程视频&#xff0c;[官方文档](多用户编辑入门 | 虚幻引擎文档 (unrealengine.com))也有教程。 这里做一下简要记录。 1.启用插件 首先打开Multi-User Edi…

SoftPerfect NetWorx中管理流量和宽带设备工具

SoftPerfect NetWorx中管理流量和宽带设备工具 NetWorx是用于在Windows中管理流量和宽带设备的简单工具和实用程序。如果我们利用交通设施&#xff0c;毫不拖延地利用教育系统&#xff0c;以及与各种驾驶员相关的学习&#xff0c;那么当加载互联网时&#xff0c;通过软件秘密使…

[附源码]计算机毕业设计酒店客房管理系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

BaiqiSoft MstHtmlEditor for .NET负责编辑的控制器

BaiqiSoft MstHtmlEditor for .NET负责编辑的控制器 BaiqiSoft MstHtmlEditor获取.NET for win表单被认为是一个元素,用户可以轻松灵活地将其融入到C#、VB.NET甚至WPF软件中。负责编辑的控制器,.NET Win Forms的MstHtmlEditor,允许用户和开发人员,甚至非技术用户使用该系列…

Docker入门第二期

写目一、宿主机与容器之间的文件拷贝二、数据卷三、数据卷容器四、Dockerfile一、宿主机与容器之间的文件拷贝 docker run -p 3307:3306 --name mysql1 -di -v /home/javaxl/data/mysql/mysql.conf.d/:/etc/mysql/mysql.conf.d/ -v /home/javaxl/data/mysql/data/:/var/lib/…

用Python把附近的足浴店都给采集了一遍,好兄弟:针不戳~

前言 嗨喽&#xff0c;大家好呀~这里是爱看美女的小编 又到了学Python时刻~ &#xff08;文末送读者福利&#xff09; 我又来了&#xff01;今天整个好玩的&#xff0c;你们肯定喜欢~ 咱们上班累了&#xff0c;不得好好犒劳一下自己&#xff0c;是吧 &#xff01; 于是我整…