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

【一篇即毕业系列】C++的引用从基础到通天

文章目录

    • 一、基础概念
    • 二、引用的特性
      • 1. 引用是别名
      • 2. 引用必须初始化
      • 3. 引用不能重新绑定
      • 4. 引用没有独立的内存地址
    • 三、使用场景
      • 1. 函数参数传递
      • 2. 函数返回值
      • 3. 避免大对象拷贝
    • 四、传值 vs 传引用的效率对比
      • 传值
      • 传引用
      • 效率对比示例
    • 五、常引用
      • 常引用的优势
    • 六、权限放大、缩小、不变
      • 1. 权限不变(推荐)
      • 2. 权限缩小(允许)
      • 3. 权限放大(不允许)
      • 函数参数中的权限规则
    • 七、引用 vs 指针
      • 相似点
      • 主要区别
      • 代码对比
      • 使用建议
    • 总结

首先列出一下csdn 引用的经典文章:
csdn引用理解
这篇文章讲的非常好。

然后我们开始本文讲解:

我来为你详细讲解C++的引用,从基础概念到高级特性。

一、基础概念

**引用(Reference)**是C++中的一种复合类型,它是某个已存在变量的别名。引用不占用额外的存储空间,它只是目标变量的另一个名字。

inta=10;int&ref=a;// ref是a的引用,即a的别名

关键点:

  • 引用必须在声明时初始化
  • 引用一旦初始化,就不能重新绑定到其他变量
  • 引用必须引用有效的对象,不能是NULL

二、引用的特性

1. 引用是别名

intx=5;int&ref=x;ref=10;// 修改ref就是修改x,x现在也是10

2. 引用必须初始化

int&ref;// 错误!引用必须初始化inta=5;int&ref=a;// 正确

3. 引用不能重新绑定

inta=5,b=10;int&ref=a;ref=b;// 这不是重新绑定,而是将b的值赋给a

4. 引用没有独立的内存地址

inta=5;int&ref=a;cout<<&a<<endl;// 输出相同的地址cout<<&ref<<endl;// 输出相同的地址

三、使用场景

1. 函数参数传递

voidswap(int&a,int&b){inttemp=a;a=b;b=temp;}intmain(){intx=5,y=10;swap(x,y);// x和y的值会被交换}

2. 函数返回值

int&getElement(intarr[],intindex){returnarr[index];// 返回引用,可以修改数组元素}intmain(){intarr[5]={1,2,3,4,5};getElement(arr,2)=100;// 修改arr[2]为100}

3. 避免大对象拷贝

structBigData{intdata[1000];};voidprocess(constBigData&data){// 使用引用避免拷贝大对象}

四、传值 vs 传引用的效率对比

传值

voidfunc(intx){x=x+1;}intmain(){inta=5;func(a);// a的值不变,因为传递的是副本}

特点:

  • 会创建参数的副本
  • 对于基本类型(int, char等)效率差异不大
  • 对于大对象(结构体、类对象)会有明显的性能开销

传引用

voidfunc(int&x){x=x+1;}intmain(){inta=5;func(a);// a的值会改变}

特点:

  • 不创建副本,直接操作原对象
  • 对于基本类型效率提升不明显
  • 对于大对象效率提升显著

效率对比示例

#include<iostream>#include<chrono>structLargeStruct{intdata[10000];};voidbyValue(LargeStruct s){s.data[0]=1;}voidbyReference(LargeStruct&s){s.data[0]=1;}intmain(){LargeStruct obj;autostart1=std::chrono::high_resolution_clock::now();for(inti=0;i<10000;i++){byValue(obj);}autoend1=std::chrono::high_resolution_clock::now();autostart2=std::chrono::high_resolution_clock::now();for(inti=0;i<10000;i++){byReference(obj);}autoend2=std::chrono::high_resolution_clock::now();// 传引用会明显快于传值}

五、常引用

常引用用于防止通过引用修改被引用的对象:

voidprintValue(constint&ref){cout<<ref<<endl;// ref = 10; // 错误!不能通过常引用修改值}intmain(){inta=5;printValue(a);// 可以传递printValue(10);// 也可以传递临时对象}

常引用的优势

  1. 防止意外修改
  2. 可以接受临时对象(右值)
  3. 提高代码安全性

六、权限放大、缩小、不变

1. 权限不变(推荐)

inta=10;int&ref=a;// 权限不变:可变→可变constint&cref=a;// 权限缩小:可变→不可变constintb=20;constint&cref2=b;// 权限不变:不可变→不可变

2. 权限缩小(允许)

inta=10;constint&ref=a;// 允许:从可变到不可变

3. 权限放大(不允许)

constinta=10;int&ref=a;// 错误!不能从不可变到可变

函数参数中的权限规则

voidfunc1(int&ref){// 需要可变引用}voidfunc2(constint&ref){// 可以接受可变和不可变引用}intmain(){inta=10;constintb=20;func1(a);// 正确func1(b);// 错误!权限放大func2(a);// 正确func2(b);// 正确}

七、引用 vs 指针

相似点

  • 都可以用来间接访问对象
  • 都可以作为函数参数传递

主要区别

特性引用指针
初始化必须初始化可以不初始化
重新绑定不能重新绑定可以重新指向其他对象
空值不能为NULL可以为nullptr
内存占用通常不占用额外内存占用指针大小的内存
运算符使用&声明,直接使用使用*声明和解引用
语法int& ref = a;int* ptr = &a;

代码对比

// 引用inta=10;int&ref=a;ref=20;// 直接使用// 指针inta=10;int*ptr=&a;*ptr=20;// 需要解引用// 指针可以重新指向intb=30;ptr=&b;// 正确// 引用不能重新绑定int&ref2=a;ref2=b;// 这是赋值,不是重新绑定

使用建议

  • 使用引用的情况

    • 参数传递(特别是大对象)
    • 函数返回值
    • 确定总是有效的情况
    • 需要简洁语法时
  • 使用指针的情况

    • 需要重新绑定
    • 需要表示"无值"(nullptr)
    • 需要指针运算
    • 实现数据结构(链表、树等)

总结

引用是C++中强大的特性,它提供了:

  • 高效的参数传递机制
  • 简洁的语法
  • 更好的代码安全性(配合const使用)

理解引用的特性、权限规则以及与指针的区别,对于编写高效、安全的C++代码至关重要。在实际开发中,优先使用引用(特别是const引用)来传递参数,可以显著提高代码的效率和可读性。

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

相关文章:

  • 仅剩72小时!生态环境部新发布的《污染预测模型R实现规范》(HJ 1308-2024)强制适配倒计时(含兼容性迁移速查表)
  • 2026 本科生论文工具盘点:9 款 AI 工具搞定初稿 / 绘图 / 排版 / AI 率
  • leetcode 1389. Create Target Array in the Given Order 按既定顺序创建目标数组-耗时100
  • 国内免费AI聊天网站大全:稳定直连与高效响应指南
  • 从零开始了解数据采集——制造业数字孪生
  • 2026年北京老人陪护企业怎么选择,北京吉至嘉家政是优选 - myqiye
  • Web原生数据库工具选型指南:SQLynx vs Navicat在云环境下的真实表现
  • 探讨创新能力强的超薄弹簧不锈钢带加工厂,哪家口碑好? - 工业设备
  • 通义千问1.5-1.8B-Chat-GPTQ-Int4应用:AIGC内容创作中的提示词优化
  • 破局与共生:制造业数字化浪潮下的机床网络推广新生态 - 品牌推荐大师
  • [DotNet] Linux 下如何编译,才能得到一个不依赖任何 so 的独立二进制文件?
  • 树莓派5实战:用NCNN跑通YOLOv5目标检测(附完整代码)
  • 集对分析法在供应链风险管理中的5个典型应用场景(含Excel模板)
  • 每周读书与学习-Jmeter中如何使用Bean Shell脚本(三)Bean Shell的基础语法之运算符和控制流语句
  • Swift-All轻量化客户端:一键部署API,快速集成大模型能力
  • 2026年毕业季:别乱用AI了!这是我测评11款工具后的终极避坑指南
  • 2026最新版!AI免费tokens全攻略,零成本玩转OpenClaw
  • MiniCPM-o-4.5-nvidia-FlagOS详细步骤:WSL2环境下CUDA驱动与模型部署兼容方案
  • SecGPT-14B镜像免配置优势:CSDN平台预装模型,省去HuggingFace下载与量化步骤
  • 2026年重庆新房装修服务推荐,港宏装饰打造品质家居 - 工业品牌热点
  • 讯飞创意组竞赛备赛指南:从零到获奖的完整流程与经验分享
  • 2025年AI图像生成器终极指南:从创意到商业应用
  • 腾讯云CentOS7部署Nacos 2.x完整指南:从端口配置到防火墙设置
  • 国密算法SM2 vs RSA:实战性能对比与迁移指南(附测试代码)
  • 造相Z-Image模型v2夜景生成效果展示:光影与氛围的精准控制
  • 总结2026年重庆新房装修,推荐几家口碑出众的公司 - mypinpai
  • 小红书运营新姿势:用xiaohongshu-mcp和AI对话搞定批量发布,非技术也能轻松上手
  • Qwen3-0.6B-FP8实战:构建一个能读“小说”并回答问题的智能书童
  • YOLO12 GPU算力适配:A10/A100/V100多卡环境下YOLO12分布式推理
  • FedMeta: Revolutionizing Federated Learning with Meta-Learning for Faster Convergence and Lower Comm