当前位置: 首页 > news >正文

C++:引用

前言:

C++ 中引用源于C指针的痛点:

C语言中的指针,不仅语法复杂(*、&满天飞),容易因空指针、野指针出错,地址操作导致代码难读,且需手动进行NULL检查。

为此,C++之父Bjarne Stroustrup在设计C++时,旨在保留指针功能同时提升安全性与简洁性,最终在C++ 2.0(1989年)引入了引用,以简化语法并增强安全性。

引用的定义:

在C++中,引用(Reference)是一种为已经存在的变量创建别名的方法。通过引用,我们可以直接操作原始变量,而不需要使用指针。(简单来讲,引用就是给变量起别名)

引用就是别名绑定:引用必须在声明时初始化,且一旦绑定到一个变量,就不能再指向其他变量(即不可重新绑定)。

对引用的使用:

int a = 10; int &r = a; // r是a的引用(别名),r和a代表同一块内存 r = 20; // 相当于 a = 20

引用与指针及值传递的对比:

这里举一个特别经典的例子,交换两个整型变量中的数字:

//交换两个整型变量中的数字 void swap1(int& n, int& m) { int temp = n; n = m; m = temp; } void swap2(int* n, int* m) { int temp = *n; *n = *m; *m = temp; } void swap3(int n, int m) { int temp = n; n = m; m = temp; }

swap3是普通的值传递,如果按照swap3函数进行操作,最终会发现两个变量中的数字并未交换,这是因为,按值传递的时候,实质上是将实参复制了一份给了形参,并未对实参进行任何操作,所以,总结下来就会发现,按值传递,对形参的操作,并不会对实参产生影响。

这个时候,我们想到使用指针就能解决这个问题了,如上述代码中的swap2函数,结果和预想的一样,两个变量中的值确实交换了。在这个函数中的指针的操作还是比较简单的。swap2中的代码,对指针变量进行了解引用操作,如果指针为NULL,对其使用*操作符解引用将导致段错误,程序会直接崩溃。所以我们一般要对指针变量进行判空操作。如果大家向上面的swap2中的代码一样忘记或者未对指针变量进行判空,这将会酿成大错。而且不知道大家有没有一种感觉,虽然指针的功能很强大,但是指针要取地址,解引用,对其理解起来是比较麻烦的。

所以这个时候就有了引用的出现,如上述代码中的swap1函数一样,使用引用的概念来解决这个问题,不仅能成功操作,而且比指针的操作简单,更为安全。使用引用实际上就是在对实参所在的空间进行操作。因为:

引用就是给这个变量所存在的这片空间起一个别名,虽然有着不同的名字,但是指向的空间是同一片空间。

引用的注意事项:

1.定义引用变量的时候必须对其进行初始化。

2.不存在空引用,或者说不能定义空引用。

eg: int& num; //这种写法是错误的。

3.没有引用的引用 或者 说是二级引用,这一说法的存在

引用的本质:

引用的本质就是指针,但是并不是普通的指针,引用实际上是常量指针(eg:int * const p=&a)。

因为变量的引用,起的别名,别名和原名虽然不同名,但是二者永远指向的是同一片空间,也不会改变他们指向的空间。常量指针的定义就是指针本身是常量,不能修改其指向的地址,但可以通过指针修改指向的内容。

所以说引用的本质就是常量指针。

指针与引用的区别:

1.从语法规则上讲,指针中存储的是某个实例变量的地址;

引用是对某个实例变量起别名。

2.系统需要给指针分配存储空间,而不需要给引用分配额外的空间。

3.使用指针所指向值的时候,需要对指针进行解引用。但是引用可以直接使用。

4.指针变量自身的值可以改变,来存储不同实例变量的地址,但是引用在定义的时候,就被初始化了,之后是无法进行改变的。

5.指针变量的值可以为空,但是引用不能为空,必须初始化,没有空引用的概念。

6.指针变量在函数中作形参的时候,在函数体中需要对其进行判空操作,但是引用不需要判空,引用没有空引用的概念。

所以总结一下:函数中使用引用比使用指针更为安全(在函数中优先考虑使用引用)

7.指针使用sizeof()对其进行计算的时候,得到的是指针变量的大小,而对引用进行操作的时候,sizeof()得到的结果是变量本身的大小

8.理论上讲,指针的级数没有没有限制,但是引用只有一级(即:没有引用的引用这一概念的存在)

9.对指针变量进行操作,可以指向下一个实体的地址,不会对实体本身进行改变。但是对引用来说是直接对实体变量本身进行改变。

http://www.jsqmd.com/news/511267/

相关文章:

  • 盘点好用的食用菌品鉴培训机构,立新菌种培训学校上榜了吗 - 工业品网
  • 新设备用不好?“视频教程+实操考核”,新手7天上手
  • LangChain:如何通过 Harness Engineering 提升 Agent 表现
  • Qwen3-VL-8B MySQL安装配置智能助手:根据报错截图提供解决方案
  • 5.2 防火墙的结构和原理
  • Protocol Launcher 系列:macOS 原生应用的深度集成(三)
  • Java类和对象(三)
  • 深度剖析 Java 类初始化机制:从<clinit>()/<init>() 字节码到静态内部类懒加载实战
  • 毕设程序java苏州旅游指南网站 基于Java的姑苏城文旅信息服务平台 SpringBoot框架下的苏州文旅导览系统
  • 吉林开顶集装箱厂价格多少,正斌集装箱费用分析 - mypinpai
  • 回归分析WebApp实验室:数据驱动的可视化建模与智能分析
  • Qwen3-32B-Chat镜像免配置优势:省去CUDA/PyTorch/transformers手动安装环节
  • 毕设程序java学生心理健康教育系统 基于SpringBoot的大学生心理成长辅导服务平台 高校学生心理素养培育与咨询管理系统
  • Stable-Diffusion-v1-5-Archive 浏览器端集成:使用JavaScript实现实时风格迁移演示
  • SenseVoice-small效果验证:法庭庭审录音法律术语高精度识别案例
  • 超酷DIY壁障自平衡小车,一文全解析
  • 网络安全考量:保护cv_unet_image-colorization API接口免受攻击
  • Qwen-Image镜像完整指南:涵盖启动、测试、调试、扩展的全生命周期管理
  • LumiPixel实战:用AI生成惊艳像素人像,效果实测分享
  • Kettle9.4(Pentaho Data Integration)调度PostgreSQL18存储过程或函数,在传入指定日期时优先指定日期,未传入指定日期默认T-1昨天
  • PHP 8 新特性、Laravel/Hyperf 源码理解、MySQL 索引优化、Redis 场景应用的庖丁解牛
  • 【限时解密】Dify 0.12+版本Multi-Agent热协同协议:支持200+并发Agent动态协商,延迟<87ms——附性能调优checklist》
  • Vue—条件渲染与循环渲染
  • 代码随想录一刷记录Day1—— leetcode704. 二分查找 leetcode27. 移除元素 leetcode977.有序数组的平方
  • EasyCVR视频届的万能接口
  • Fun-ASR-MLT-Nano实战:搭建支持31种语言的语音识别服务
  • java微信小程序的外卖点餐点单系统 商家协同过滤
  • VOOHU 沃虎电子 SFP28 高速连接器 WHSFP32221F013 集成导光柱与散热孔 满足25G数据中心高密度应用
  • 提升自控力差孩子的学习生活:有效的学习障碍帮助与冲动控制训练方法
  • 2026年3月,评测精选皮带导轨厂家,导轨品牌分析深度剖析助力明智之选 - 品牌推荐师