【C++基础】引用(引用的概念;引用的特性;常引用;使用场景:做输出型参数、大对象传参、做输出型返回值、返回大对象的引用);引用和指针的区别)
六、引用
6.1 引用的概念
-
引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。(语法上)
-
格式:类型& 引用变量名(对象名) = 引用实体;
void TestRef()
{int a = 10;int& ra = a;//<====定义引用类型printf("%p\n", &a);printf("%p\n", &ra);
}
注意:引用类型必须和引用实体是同种类型的
6.2 引用的特性
- 引用在定义时必须初始化
- 一个变量可以有多个引用
- 引用一旦引用一个实体,再不能引用其他实体

说明:
- int& d = c; //c是a变量的别名,再为c取别名实际上还是引用a。相当于:int& d = a;
- b = x; //b是a的别名,这句相当于:a = x; 将x赋值给b(a);
6.3 常引用
常引用即引用的类型用const进行修饰,表示不能通过该引用修改引用对象的值。类似于常量指针:const int *p;
- 权限不能放大
- 权限可以缩小
- 显示或隐式类型转换都会产生同类型的临时变量,产生的临时变量具有常性。
void TestConstRef()
{//权限不能放大const int a = 20;//int& ra = a;const int& ra = a;//权限可以缩小int b = 30;const int& rb = b;//类型转换产生临时变量,产生的临时变量具有常性int i = 1;double d = i; //类型转换的过程中会产生同类型的临时变量//double& rd = i; //产生的临时变量具有常性 const double &rd = i; //此处临时变量的类型是const double
}

说明:
- 权限放大或缩小的问题只存在于引用或指针上。普通变量不存在,因为普通变量不对源值做修改,只做值拷贝。
- 如果使用引用传参,函数内如果不改变源值(输入型参数),那么建议尽量用const引用传参,提高程序的健壮性,且这样的形参具有非常强的接收度(类型转换)。
6.4 使用场景
1. 做输出型参数
引用做输出型参数,相比指针传参,使用更加方便。
void Swap(int& left, int& right){int temp = left;left = right;right = temp;
}
int main(){int a = 0, b = 2;Swap(a,b);return 0;
}
2. 大对象传参
以值作为参数或者返回值类型,在传参和返回期间,函数不会直接传递实参或者将变量本身直接返回,而是传递实参或者返回变量的一份临时的拷贝,因此用值作为参数或者返回值类型,效率是非常低下的,尤其是当参数或者返回值类型非常大时,效率就更低。
- 我们可以做以下测试:
#include <time.h>
struct A{ int a[10000]; };
void TestFunc1(A a){}
void TestFunc2(A& a){}
void TestRefAndValue()
{
A a;
// 以值作为函数参数
size_t begin1 = clock();
for (size_t i = 0; i < 10000; ++i)
TestFunc1(a);
size_t end1 = clock();
// 以引用作为函数参数
size_t begin2 = clock();
for (size_t i = 0; i < 10000; ++i)
TestFunc2(a);
size_t end2 = clock();
// 分别计算两个函数运行结束后的时间
cout << "TestFunc1(A)-time:" << end1 - begin1 << endl;
cout << "TestFunc2(A&)-time:" << end2 - begin2 << endl;
}
- 测试结果:

- 得出结论:大对象使用引用传参,提高效率,节省空间。
3. 做输出型返回值
做输出型返回值,调用者可以修改返回对象。
int& Count()
{static int n = 0;n++;// ...return n;
}
同指针一样,不能返回局部变量的引用。但可以返回静态区或堆空间变量的引用。
4.(误区警示)返回局部变量的引用
下面代码输出什么结果?为什么?
int& Add(int a, int b)
{int c = a + b;return c;
}
int main()
{int& ret = Add(1, 2);Add(3, 4);cout << "Add(1, 2) is :"<< ret <<endl;return 0;
}
- 测试结果:

- 解释原因:

- 得出结论:函数返回后,函数内的局部变量(栈帧空间)就销毁了。那么一定不能返回局部变量的引用,只能传值返回。
5. 返回大对象的引用
返回大对象的引用可以减少拷贝,提高效率。
- 我们可以做以下测试:
#include <time.h>
struct A{ int a[10000]; };
A a;
// 值返回
A TestFunc1() { return a;}
// 引用返回
A& TestFunc2(){ return a;}
void TestReturnByRefOrValue()
{
// 以值作为函数的返回值类型
size_t begin1 = clock();
for (size_t i = 0; i < 100000; ++i)
TestFunc1();
size_t end1 = clock();
// 以引用作为函数的返回值类型
size_t begin2 = clock();
for (size_t i = 0; i < 100000; ++i)
TestFunc2();
size_t end2 = clock();
// 计算两个函数运算完成之后的时间
cout << "TestFunc1 time:" << end1 - begin1 << endl;
cout << "TestFunc2 time:" << end2 - begin2 << endl;
}
- 测试结果:

- 得出结论:结合大对象的传参和返回测试,我们可以看出传值和引用在作为传参以及返回值类型上效率相差很大。
6.5 引用和指针的区别
在语法概念上引用就是一个别名,没有独立空间,和其引用的实体共用同一块空间。
#include <iostream>
using namespace std;
int main()
{ int a = 10; int& ra = a; int* pa = &a; cout<<"a = "<<a<<endl; cout<<"ra = "<<ra<<endl; cout<<"pa = "<<pa<<endl; cout<<"*pa = "<<*pa<<endl<<endl; cout<<"&a = "<<&a<<endl; cout<<"&ra = "<<&ra<<endl; cout<<"&pa = "<<&pa<<endl; cout<<"pa = "<<pa<<endl;
return 0;
}
测试结果:

在底层实现上实际是有空间的,因为引用是按照指针方式来实现的。
int main()
{
int a = 10;
int& ra = a;
ra = 20;
int* pa = &a;
*pa = 20;
return 0;
}
我们来看下引用和指针的汇编代码对比:

底层汇编完全相同,说明引用是按照指针的方式来实现的。
引用和指针的不同点:
- 引用概念上定义一个变量的别名,指针存储一个变量地址。
- 引用在定义时必须初始化,指针没有要求。
- 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何一个同类型实体。
- 没有NULL引用,但有NULL指针。
- 在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32位平台下占4个字节)。
- 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小。
- 有多级指针,但是没有多级引用。
- 访问实体方式不同,指针需要显式解引用,引用编译器自己处理。
- 引用比指针使用起来相对更安全。
总结:
- 指针更强大,更危险,更复杂;
- 引用相对局限一些,更安全,更简单;
相关文章:
【C++基础】引用(引用的概念;引用的特性;常引用;使用场景:做输出型参数、大对象传参、做输出型返回值、返回大对象的引用);引用和指针的区别)
六、引用 6.1 引用的概念 引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。(语法上) 格式:类型& 引用变量名(对象名) …...
Redis只用来做缓存?来认识一下它其他强大的能力吧。
当今互联网应用中,随着业务的发展,数据量越来越大,查询效率越来越高,对于时序数据的存储、查询和分析需求也越来越强烈,这时候 Redis 就成为了首选的方案之一。 Redis 提供了多种数据结构,如字符串、哈希表…...
【ES】数据同步集群
【ES】数据同步&集群3.数据同步3.1.思路分析3.1.1.同步调用3.1.2.异步通知3.1.3.监听binlog3.1.4.选择3.2.实现数据同步3.2.1.思路3.2.2.导入demo3.2.3.声明交换机、队列1)引入依赖2)声明队列交换机名称3)声明队列交换机3.2.4.发送MQ消息…...
37岁男子不愿熬夜,回乡养鸡每天准时下班,青山绿水中养鸡,直播间里卖鸡蛋...
37岁男子不愿熬夜,回乡养鸡每天准时下班,青山绿水中养鸡,直播间里卖鸡蛋。今天和大家分享一个创业案例,他叫胡铭浩,来自安徽省旌德县,今年37岁,曾做过车床操作工,开过婚纱摄影店&…...
深度学习和人工智能之间是什么样的关系?
深度学习与人工智能概念的潜在联系,我们依然借助维恩图来说明,如图4.1所示。 1、人工智能 “人工智能”这个概念新鲜时髦但又含混模糊,同时包罗万象。尽管如此,我们仍尝试对 人工智能进行定义:用一台机器处理来自其周围环境的信息,然后将这些…...
实战打靶集锦-016-lampiao
提示:本文记录了博主打靶过程中一次曲折的提权经历 文章1. 主机发现2. 端口扫描3. 服务枚举4. 服务探查4.1 80端口探查4.2 1898端口探查4.3 EXP搜索4.3.1 exploit/unix/webapp/drupal_coder_exec4.3.2 exploit/unix/webapp/drupal_drupalgeddon25. 提权5.1 系统信息…...
《Web前端应用开发》考试试卷(模拟题)
一、产品搜索页面 打开“考试文件夹”中的input.html,完成以下步骤: 注意:本题仅能在input.html的(1)为产品名称所在的div添加样式属性,使得产品名称保持在文本框的左边; (2…...
【react全家桶学习】react简介
react是什么? react是用于构建用户界面的JS库,是一个将数据渲染为HTML视图的开源JS库 谁开发的? 由Facebook开发,且开源 为什么要学? 原生JavaScript操作DOM繁琐、效率低 ( DOM-API操作 UI)使用JavaScript直接操作…...
此战成硕,我成功上岸西南交通大学了~~~
友友们,好久不见,很长时间没有更一个正式点的文章了! 是因为我在去年年底忙着准备初试,今年年初在准备复试,直到3月底拟录取后,终于可以写下这篇上岸贴,和大家分享一下考研至上岸的一个过程 文章…...
光耦继电器工作原理及优点概述
光耦继电器是一种电子元器件,也是固态继电器的一种,其主要作用是隔离输入与输出电路,用于保护或者控制电路的正常工作。 光耦继电器工作原理是利用光电转换器将外界信号转化为光信号,通过光纤传输到另一端,再由另一端的…...
【Mysql】mysql8.0.26解压包部署方式
版本背景: 操作系统:centos7.3 mysql版本:mysql-8.0.26-linux-glibc2.12-x86_64.tar 一、前期准备 1、检测操作系统自带安装的mysql和mariadb服务,如存在,需卸载 rpm -qa | grep mysql rpm -qa | grep mariadb 卸载…...
进销存管理系统能为企业带来哪些实际效益?
随着互联网的不断发展,如今的商业世界已经越来越向数字化转型。拥有一套完整的数字化的进销存管理能够极大地提升公司货物进出库存情况的效率和准确性,避免过程中出现不必要的错误和漏洞,从而帮助企业更加稳健地自我发展。那么,一…...
图片怎么转换成pdf格式?这几个方法帮你一键转换
现今电子书籍越来越受到欢迎,其中PDF格式也成为了一种常用的电子书籍格式。无论是工作还是学习,我们都可能会遇到需要将图片转换成PDF格式的情况,例如保存一些资料证明、公文公告、学习资料等。在这篇文章中,我们将为大家介绍三种…...
数据结构exp1_2学生成绩排序
目录 数据结构exp1_2学生成绩排序 程序设计 程序分析 数据结构exp1_2学生成绩排序 【问题描述】 对某班学生成绩排序。从键盘依次输入某班学生的姓名和成绩(一个班级人数最多不超过50人)并保存,然后分别按学生成绩由高到低顺序输出学生姓名和成绩,成绩相同时,则按输…...
在DongshanPI-D1开箱使用分享与折腾记录实现MPU6050数据读取
前言 上一篇文章使用RT-Smart的IIC驱动OLED屏幕,进行基本的字符串显示,在使用过程中对RT-Smart有了一定熟悉,准备使用SPI驱动ST7789,但SPI接口没有引出,本次使用手上已有的传感器MPU6050进行使用。 过程 本次直接开始添加离线包…...
Nature子刊 定制饮食去除半胱氨酸和蛋氨酸可诱导细胞自毁进而治疗脑瘤?
恶性胶质瘤是成人最常见的脑部肿瘤。恶性胶质瘤的致死率为100%,无法治愈,是一种极度的恶性肿瘤。如此糟糕的预后促使研究者及神经外科医生不断学习研究肿瘤生物学,期望创造更好的疗法。神经外科助理教授Dominique Higgins博士从事肿瘤生物学的…...
抛弃 TCP 和 QUIC 的 HTTP
下班路上发了一则朋友圈: 周四听了斯坦福老教授 John Ousterhout 关于 Homa 的分享,基本重复了此前那篇 It’s Time To Rep… 的格调,花了一多半时间喷 TCP… Ousterhout 关于 Homa 和 TCP 之间的论争和论证,诸多反复回执&…...
未来公寓智能化设计平台项目(下)
创业场景通过在社区入口附近建设共享办公室,带动海慧园和众汽佳苑创业氛围,也让社区出了居住以外有其它功能,并且结合教育、邻里模块让社区更有活力。住户可通过app查看共享空间的使用情况,以及可以远程控制各种设备。 顺应未来生活与就业、创业融合新趋势,构建“大众创新…...
常见分布式消息队列综合对比
本文将从,Kafka、RabbitMQ、ZeroMQ、RocketMQ、ActiveMQ 17 个方面综合对比作为消息队列使用时的差异。 1. 资料文档 Kafka:中,有 kafka 作者自己写的书,网上资料也有一些。 rabbitmq:多,有一些不错的书…...
怎么邀请主流媒体到现场报道
传媒如春雨,润物细无声,大家好 主流媒体通常是指央媒,报纸杂志,电视台,地方重点媒体等,采访形式包括现场取材报道,媒体专访,群访等。通常主流媒体对选题要求较严格,因此在…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
Java 语言特性(面试系列2)
一、SQL 基础 1. 复杂查询 (1)连接查询(JOIN) 内连接(INNER JOIN):返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
mac 安装homebrew (nvm 及git)
mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用: 方法一:使用 Homebrew 安装 Git(推荐) 步骤如下:打开终端(Terminal.app) 1.安装 Homebrew…...
Webpack性能优化:构建速度与体积优化策略
一、构建速度优化 1、升级Webpack和Node.js 优化效果:Webpack 4比Webpack 3构建时间降低60%-98%。原因: V8引擎优化(for of替代forEach、Map/Set替代Object)。默认使用更快的md4哈希算法。AST直接从Loa…...
