【C++掌中宝】走进C++引用的世界:从基础到应用

news2024/9/24 14:29:38

在这里插入图片描述

文章目录

  • 引言
  • 1. 基础概念
  • 2. 引用与指针的区别
  • 3. 引用的应用场景
    • 3.1 引用作为函数参数
    • 3.2 引用作为函数返回值
    • 3.3 常引用(const引用)的使用
    • 3.4 引用与多态
  • 4. C++ 引用的优缺点
  • 5. 引用的注意事项与常见陷阱
  • 6. 总结
  • 结语

引言

C++ 引用是编写高效、简洁代码的重要工具。与指针类似,引用允许程序员以间接方式访问数据,但其使用方式更为安全和简便。在这篇博客中,我们将深入探讨 C++ 中引用的概念、特性以及使用方式,帮助你更好地理解和使用引用。

1. 基础概念

引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。比如:水浒传中李逵,宋江叫"铁牛",江湖上人称"黑旋风";林冲,外号豹子头;

在这里插入图片描述

因此对引用的任何操作都会直接影响原变量。格式如下:

类型& 引用别名 = 引用对象;

引用使用 & 符号声明,例如:

int a = 10;
int& ref = a;

在上面的例子中,refa 的引用,二者共享同一块内存区域。修改 ref 的值会直接改变 a 的值。

引用的核心特性:

  • 必须初始化:引用在声明时必须绑定到某个变量,且不能更改绑定的对象。
  • 多引用:一个变量可以有多个引用
  • 不占用额外内存:引用和原变量共用同一内存空间。
  • 引用与变量操作一致:对引用的操作会反映在其绑定的变量上。

2. 引用与指针的区别

C++中指针和引用就像两个性格迥异的亲兄弟,指针是哥哥,引用是弟弟,在实践中他们相辅相成,功能有重叠性,但是各有自己的特点,互相不可替代。

引用与指针都能实现间接访问,但二者存在以下不同点:

区别引用指针
初始化必须初始化可以延迟初始化
是否可更改指向不可更改可以更改
是否可为空不能为空(NULL)可以为空(NULL)
使用方式无需解引用符号需使用解引用符号
sizeof中的含义结果为引用类型的大小始终是地址空间所占字节个数(32位平台下占4个字节,64位平台下占8个字节)

引用的优势在于语法简洁且更安全,而指针则更灵活,但容易引发空指针或野指针问题。(从底层汇编的角度来看,引用也是用指针实现的,在底层实现上引用实际是有空间的

我们来看看引用和指针的汇编代码对比

在这里插入图片描述

3. 引用的应用场景

引用在 C++ 编程中有广泛应用,尤其是在函数参数传递和返回值中。以下是几个常见应用场景:

3.1 引用作为函数参数

引用传递能避免值传递时的拷贝操作,提升效率,尤其在处理大对象时。例如:

void modify(int &x) {
    x = 10;  // 修改外部变量
}

函数 modify 直接修改了实参 x,而不是传递一个副本。

3.2 引用作为函数返回值

函数返回引用能够避免创建副本,直接操作外部数据:

int& getElement(int arr[], int index) {
    return arr[index];
}

返回数组元素的引用,使外部可以直接修改数组内容。

总结

  • 引用在实践中主要是于引用传参和引用做返回值中减少拷贝提高效率和改变引用对象时同时改变被引用对象。

  • 引用传参跟指针传参功能是类似的,引用传参相对更方便一些。

  • 引用返回值的场景相对比较复杂,我们在这里简单讲了一下场景,还有一些内容后续类和对象章节中会继续深入讲解。

  • 引用和指针在实践中相辅相成,功能有重叠性,但是各有特点,互相不可替代。C++的引用跟其他语言的引用(如Java)是有很大的区别的,除了用法,最大的点,C++引用定义后不能改变指向,Java的引用可以改变指向。

  • 一些主要用C代码实现版本数据结构教材中,使用C++引用替代指针传参,目的是简化程序,避开复杂的指针,但是很多同学没学过引用,导致一头雾水。

3.3 常引用(const引用)的使用

常引用 (const) 用于避免修改原数据,可以理解为只读型同时可以引用常量或临时对象。例如:

void display(const int &x) {
    std::cout << x << std::endl;
}

常引用保证了传递的数据不会被修改。


权限放大

//只读型(const)
const int a = 20;
 
//可读可写型  报错!
int &b= a;      × × ×
 
//权限平移
const int &c = a;   √ √ √ 

权限缩小

//可读可写型
int e = 30;
 
//只读型
const int &f = e;     √ √ √

临时变量具有常属性

类型转换,并不会改变变量类型,中间都会产生一个临时变量!!
//临时变量具有常属性 --- 相当于被const修饰了
int ii = 1;
//发生 -- 隐式转换 -- 
double dd = ii;        //隐式类型转换是语法允许的
 
--------------------------
 
//报错   权限被放大
double &rdd = ii;      // × × × 权限被放大了
//权限的平移
const double &rdd = ii;

在这里插入图片描述


使用反例

void func1(int  n)
{}
void func2(int& n)
{}
void func3(const int& n)
{}
 
int main()
{
	int a = 10;
	const int b = 20;
	func1(a);
	func1(b);
	func1(30);
 
	func2(a);
 
	//权限被放大   -- 报错 --
	func2(b);
	//权限被放大   -- 报错 --
	func2(30);
	
	double d = 2.22;
	//权限被放大   -- 报错 --
	func2(d);
	//语法允许
	func3(d);
	return 0;
}

总结

  • 可以引用一个const对象,但是必须用const引用。const引用也可以引用普通对象,因为对象的访问权限在引用过程中可以缩小,但是不能放大

  • 权限放大和缩小只针对引用和指针

  • 不需要注意的是类似 int& rb = a*3; double d = 12.34; int& rd = d; 这样一些场景下a*3的和结果保存在一个临时对象中, int& rd = d 也是类似,在类型转换中会产生临时对象存储中间值,也就是时,rb和rd引用的都是临时对象,而C++规定临时对象具有常性,所以这里就触发了权限放大,必须要用常引用才可以。

  • 所谓临时对象就是编译器需要一个空间暂存表达式的求值结果时临时创建的一个未命名的对象,C++中把这个未命名对象叫做临时对象。

3.4 引用与多态

在多态场景中,引用可以通过基类指向派生类,实现多态行为:

class Base {
public:
    virtual void show() { std::cout << "Base" << std::endl; }
};

class Derived : public Base {
public:
    void show() override { std::cout << "Derived" << std::endl; }
};

void display(Base &obj) {
    obj.show();  // 基类引用可指向派生类
}

4. C++ 引用的优缺点

优点

  • 语法简化,操作更加直观。
  • 避免空指针或野指针问题。
  • 减少拷贝,提高函数调用效率。

缺点

  • 必须在声明时初始化,灵活性不如指针。
  • 一旦初始化不能更改指向对象。
  • 使用不当时可能导致悬空引用。

5. 引用的注意事项与常见陷阱

  • 不要返回局部变量的引用:局部变量在函数结束后会被销毁,返回其引用会导致悬空引用。
  • 避免引用无效内存:确保引用指向合法的内存空间,避免运行时错误。
  • 引用与指针的混用:引用虽然简化了很多操作,但并不能完全替代指针,特别是在涉及动态内存管理时。

6. 总结

C++ 引用是简化代码、提高程序效率的重要工具,特别是在参数传递、返回值优化等场景中发挥了重要作用。与指针相比,引用更加简洁、安全,但在灵活性上有所限制。通过正确理解和使用引用,可以让你的 C++ 代码更加高效、稳健。

结语

希望这篇博客能帮助你深入理解 C++ 中的引用。祝你在编程的旅途中不断进步!如有任何问题或需要进一步讨论的内容,欢迎在评论区留言交流!

今天的分享到这里就结束啦!如果觉得文章还不错的话,可以三连支持一下。

也可以点点关注,避免以后找不到我哦!

Crossoads主页还有很多有趣的文章,欢迎小伙伴们前去点评,您的支持就是作者前进的动力!

在这里插入图片描述

参考:【C++】之引用详解 什么是引用?_c++引用-CSDN博客

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

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

相关文章

计算机视觉实战项目4(图像分类+目标检测+目标跟踪+姿态识别+车道线识别+车牌识别+无人机检测+A*路径规划+单目测距与测速+行人车辆计数等)

往期热门项目回顾&#xff1a; 计算机视觉项目大集合 改进的yolo目标检测-测距测速 路径规划算法 图像去雨去雾目标检测测距项目 交通标志识别项目 yolo系列-重磅yolov9界面-最新的yolo 姿态识别-3d姿态识别 深度学习小白学习路线 AI健身教练-引体向上-俯卧撑计数…

【JVM】JVM执行流程和内存区域划分

是什么 Java 虚拟机 JDK&#xff0c;Java 开发工具包JRE&#xff0c;Java 运行时环境JVM&#xff0c;Java 虚拟机 JVM 就是 Java 虚拟机&#xff0c;解释执行 Java 字节码 JVM 执行流程 编程语言可以分为&#xff1a; 编译型语言&#xff1a;先将高级语言转换成二进制的机器…

爆火南卡开放式耳机,音质性能霸榜TOP1,行业唯一达专业HiFi级音质标准!

爆火南卡开放式耳机&#xff0c;音质性能霸榜TOP1&#xff0c;行业唯一达专业HiFi级音质标准&#xff01; 随着科技的不断进步&#xff0c;耳机市场迎来了又一次革命性的创新。南卡&#xff08;NANK&#xff09;品牌近日宣布&#xff0c;其最新力作——南卡Ultra耳夹开放式耳机…

大模型榜单汇总整理

大型语言模型&#xff08;LLM&#xff09;评估榜单提供了对不同模型性能的标准化比较&#xff0c;涵盖了从通用能力到特定领域应用的多个方面。这些榜单专注于评估模型在特定领域的应用能力&#xff0c;有助于开发者了解模型的优势和局限性&#xff0c;推动语言模型的发展和优化…

彩虹表攻击

彩虹表攻击是一种通过查找预计算哈希值来破解密码的技术。攻击者会生成一个包含大量常见密码及其哈希值的查找表&#xff0c;随后将这些哈希值与数据库中的密码哈希进行匹配&#xff0c;从而快速找出对应的明文密码。该攻击方法特别适用于使用弱密码且未进行加盐处理的系统。 相…

Spring Cloud Alibaba-(6)Spring Cloud Gateway【网关】

Spring Cloud Alibaba-&#xff08;1&#xff09;搭建项目环境 Spring Cloud Alibaba-&#xff08;2&#xff09;Nacos【服务注册与发现、配置管理】 Spring Cloud Alibaba-&#xff08;3&#xff09;OpenFeign【服务调用】 Spring Cloud Alibaba-&#xff08;4&#xff09;Sen…

Windows电脑使用VNC远程桌面本地局域网内无公网IP树莓派5

目录 前言 1. 使用 Raspberry Pi Imager 安装 Raspberry Pi OS 2. Windows安装VNC远程树莓派 3. 使用VNC Viewer公网远程访问树莓派 3.1 安装Cpolar步骤 3.2 配置固定的公网地址 3.3 VNC远程连接测试 4. 固定远程连接公网地址 4.1 固定TCP地址测试 作者简介&#xff1…

在Windows系统上安装的 Arrow C++ 库

在Windows系统上安装的 Arrow C 库 正文第一步第二步第三步第四步注: 检查是否安装成功 吐槽 正文 第一步 git clone gitgithub.com:apache/arrow.git第二步 打开powershell (好像cmd也可以,不过我试了powershell中不报错,cmd中报错,不是很清楚为什么) 打开arrow的目录 cd …

利士策分享,如何培养良好的工作习惯?

利士策分享&#xff0c;如何培养良好的工作习惯&#xff1f; 在这个快节奏、高压力的职场环境中&#xff0c;培养良好的工作习惯不仅关乎个人职业发展的顺畅度&#xff0c; 更是提升工作效率、保持身心健康的关键。 以下是一些实用的建议&#xff0c;帮助你在日常工作中逐步构…

fiddler监听安卓http请求

下载安装Fiddler 官网 配置 选择Options 打开模拟器找到设置 打开app请求就能实现接口的监听了 https需要单独处理 参考 https://blog.csdn.net/lengdaochuqiao/article/details/88170522

靠AI视频在短视频平台接单月入过万,她怎么做到的?AI视频真的来了

大家好&#xff0c;我是画画的小强 相信大家和我一样&#xff0c;从小也有一个导演梦&#xff0c;感谢AI时代&#xff0c;替我完成了这个梦想&#xff0c;如果你想知道如何实现的&#xff0c;今天这篇文章&#xff0c;你一定要看完&#xff01; 从去年11月份起&#xff0c;随…

MISC - 第三天(MSB二进制高地址位,ASCII编码,brainfuck编码)

前言 各位师傅大家好&#xff0c;我是qmx_07&#xff0c;今天继续讲解MISC题目 被嗅探的流量 观察题目信息&#xff0c;猜测可能是通过http网址传输文件&#xff0c;也可以查询内网ip进行筛查 过滤http协议&#xff0c;发现upload.php路径 查询POST提交请求 在第二条数据里…

【Python报错已解决】NameError: name ‘reload‘ is not defined

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 专栏介绍 在软件开发和日常使用中&#xff0c;BUG是不可避免的。本专栏致力于为广大开发者和技术爱好者提供一个关于BUG解决的经…

开学季好物合集!带你揭秘2024最全数码好物清单!学生党必看!

开学季总是令人充满期待与憧憬。对于学生党来说&#xff0c;拥有合适的学习装备和数码好物&#xff0c;不仅能提升学习效率&#xff0c;还能为校园生活增添诸多便利与乐趣。在科技飞速发展的今天&#xff0c;数码产品的更新换代日新月异&#xff0c;市场上琳琅满目的数码好物让…

数据结构算法题

目录 轮转数组原地移除数组中所有元素val删除有序数组中的重复项合并两个有序数组 轮转数组 思路1&#xff1a; 1.利用循环将最后一位数据放到临时变量&#xff08;n&#xff09;中 2.利用第二层循环将数据往后移一位 3.将变量&#xff08;n&#xff09;的数据放到数组第一位 时…

slam入门学习笔记

SLAM是Simultaneous localization and mapping缩写&#xff0c;意为“同步定位与建图”&#xff0c;主要用于解决机器人在未知环境运动时的定位与地图构建问题&#xff0c;目前广泛用于机器人定位导航领域&#xff0c;VR/AR方面&#xff0c;无人机领域&#xff0c;无人驾驶领域…

9.23每日作业

仿照string类&#xff0c;自己手动实现 My_string list.h #ifndef LIST_H #define LIST_H #include <iostream>using namespace std;class My_string { private:char *ptr;int size;int len;public://无参构造My_string();//有参构造My_string(const char * src);My_st…

哈希——字符串哈希

回顾/本期梗概 上期我们学习了图论基础&#xff08;空降链接&#xff09;&#xff0c;本期我们将学习哈希中的字符串哈希。 1、什么是哈希 哈希算法是&#xff1a;通过哈希函数讲字符串、较大的数等转换为能够用变量表示的或者是直接能作为数组下标的数&#xff0c;通过哈希算法…

代码随想录算法训练营Day13 | 递归遍历、迭代遍历、层序遍历

目录 递归遍历和迭代遍历&#xff1a; 144.二叉树的前序遍历 94.二叉树的中序遍历 145.二叉树的后序遍历 层序遍历&#xff1a; 102.二叉树的层序遍历 107.二叉树的层序遍历Ⅱ 199.二叉树的右视图 637.二叉树的层平均值 429.N叉树的层序遍历 515.在每个树行中找最大…

计算机组成体系与组成结构错题解析【软考】

目录 前言进制转换码制补码 CPU的组成输入/输出技术中断相关概念输入/输出技术的三种方式比较周期相关知识 主存编址计算流水线技术层次化存储体系可靠性 前言 本文专门用来记录本人在做软考中有关计算机上组成体系与组成结构的错题&#xff0c;我始终认为教学相长是最快提高的…