C++中值传递和引用传递的区别

news/2025/1/6 16:09:07/文章来源:https://www.cnblogs.com/xiaodao0036/p/18651817

C++中值传递和引用传递的区别

值传递:在函数调用时,传递的是实际参数的副本,因此函数内对参数的修改不会影响到实际参数。
引用传递:在函数调用时,传递的是实际参数的引用,因此函数内对参数的修改会影响到实际参数。

值传递

示例代码:

class A{
public:A() {std::cout << "A constructor called" << std::endl;}A(const A& other) {std::cout << "A copy constructor called" << std::endl;}int a;
};void func(A a) {a.a = 20;
}int main() {A a;a.a = 10;std::cout << "before func call, a.a = " << a.a << std::endl;func(a);std::cout << "after func call, a.a = " << a.a << std::endl;return 0;
}

输出结果:

//传递的是副本,因此调用了拷贝构造,修改了副本,不会影响到实际参数
A constructor called
before func call, a.a = 10
A copy constructor called    //调用拷贝构造
after func call, a.a = 10

引用传递

示例代码:

class A{
public:A() {std::cout << "A constructor called" << std::endl;}A(const A& other) {std::cout << "A copy constructor called" << std::endl;}int a;
};void func(A& a) {a.a = 20;
}int main() {A a;a.a = 10;std::cout << "before func call, a.a = " << a.a << std::endl;func(a);std::cout << "after func call, a.a = " << a.a << std::endl;return 0;
}

输出结果:

//传递的是引用,因此不会调用拷贝构造,直接修改了实际参数
A constructor called
before func call, a.a = 10      
after func call, a.a = 20

使用场景

从机制上来看,值传递适用于不可变的对象,即你不希望改变原本对象的值,而引用传递适用于可变的对象,即你希望改变原本对象的值。
从性能上考虑,值传递需要拷贝对象,对于简单数据类型,两者区别较小,但对于类、结构体等复杂对象,拷贝过程可能比较耗时,而引用传递不需要拷贝对象,因此在性能上有优势。在使用上应尽可能使用引用传递来减少拷贝的开销。如果你不希望改变原本对象可以通过添加const关键字来实现

拓展

引用可以理解为一个对象的别名(底层应该是通过指针常量实现的,这个博主不太确定),因此引用在初始化时就必须绑定(先有对象存在,才能给对象起别名),而且绑定之后不能再改变。

示例代码:

class A{
public:A() {std::cout << "A constructor called" << std::endl;}A(const A& other) {std::cout << "A copy constructor called" << std::endl;}A& operator=(const A& other) {std::cout << "A copy assignment operator called" << std::endl;return *this;}int a;
};void func(A& a) {A b;b.a = 20;A& ref_b = b;//一样的效果a = ref_b;//a = static_cast<A&>(ref_b);std::cout << "func ptr a = " << &a << std::endl;std::cout << "func ptr b = " << &b << std::endl;
}int main() {A a;a.a = 10;std::cout << "main ptr a = " << &a << std::endl;std::cout << "before func call, a.a = " << a.a << std::endl;func(a);std::cout << "after func call, a.a = " << a.a << std::endl;return 0;
}

输出结果:

//地址不一致,实际调用的是赋值运算符
A constructor called
main ptr a = 0000007B772FFC14
before func call, a.a = 10
A constructor called
A copy assignment operator called
func ptr a = 0000007B772FFC14
func ptr b = 0000007B772FFAD4
after func call, a.a = 10

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

24. 两两交换链表中的节点(中)

目录题目法一、迭代法二、递归 题目给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。法一、迭代 var swapPairs = function(head) {let dummy = {next:head}let p1 = dummywhile(p1.ne…

深入理解Java虚拟机:JVM高级特性与最佳实践(第3版)PDF、EPUB免费下载

周志明JVM新作,新增内容近50%,大厂面试知识点全覆盖。与《Java编程思想、EffectiveJava、Java核心技术》堪称“Java四大名著”适读人群 :1.使用Java技术体系的中-高级开发人员 2.系统调优师 3.平台架构师 4.准备进互联网大厂面试的Java开发人员 周志明JVM新作,新增内容近50…

使用 ActiViz.Net (商业版)实现读三维地震数据可视化

一、背景 在地震勘探中,SEG-Y 格式(简称 SEGY)是最常用的数据格式之一,用于存储地震波的原始数据。地震数据通常包含了时间序列信息,并通过不同的采样和测量方法来记录地下结构的属性。为了有效地可视化这些数据,尤其是地震波的幅度和传播情况,三维可视化是一个非常有用…

使用 ActiViz.Net 实现读三维地震数据可视化

一、背景 在地震勘探中,SEG-Y 格式(简称 SEGY)是最常用的数据格式之一,用于存储地震波的原始数据。地震数据通常包含了时间序列信息,并通过不同的采样和测量方法来记录地下结构的属性。为了有效地可视化这些数据,尤其是地震波的幅度和传播情况,三维可视化是一个非常有用…

通过网址或html生成一个简单apk

GitHub - pzx521521/apk-editor 通过网址或html生成一个简单apk 之前发过一个使用apktool版本的,简单来说就是一个对apk反编译和编译的过程相比使用apktool有以下优点:[x] 没有环境依赖,完全不需要 jdk/jre [x] 无需中间调用apktool,容易部署到服务器/docker使用 Online Demo 修…

EXCEL中自动突出显示(自动高亮)行或列

EXCEL中,当选择的单元格距离列首或行首过远时,考验眼睛的时候就到了。解决方法很多,如果想要自动突出显示,就只能上vba代码了。解决的问题 EXCEL中,当选择的单元格距离列首或行首过远时,考验眼睛的时候就到了。解决方法很多,如果想要自动突出显示,就只能上vba代码了。方…

DL00868-基于深度学习的红外船舶检测识别分类完整实现数据8000+

随着遥感技术的快速发展,包括无人机、卫星等,红外图像在船舶检测识别中的作用日益凸显。相对于可见光图像,红外图像具有在夜晚和恶劣天气条件下高效检测识别船舶的天然优势。近年来,深度学习作为一种强大的图像处理技术,在红外船舶检测识别领域取得了显著进展。完整链接:…

基于深度学习的红外船舶检测识别分类完整实现数据集8000+张

随着遥感技术的快速发展,包括无人机、卫星等,红外图像在船舶检测识别中的作用日益凸显。相对于可见光图像,红外图像具有在夜晚和恶劣天气条件下高效检测识别船舶的天然优势。近年来,深度学习作为一种强大的图像处理技术,在红外船舶检测识别领域取得了显著进展。完整链接:…

第三章 MBR -- loader

第三章 MBR --> loader 本文是对《操作系统真象还原》第三章学习的笔记,欢迎大家一起交流。 a 知识介绍 在上一章的代码部分,我们通过 BIOS 中断进行字符输出,但是离开实模式之后,BIOS 中断就没法用了,因为 BIOS 中断向量表只在实模式下存在,因此我们肯定还会有别的方…

正常运行 打包后提示某些属性或者类找不到

lombok 注解未正确加载,注意 idea属性修改

itextpdf 找出PDF中 文字的坐标

目录添加引用添加工具类调用 找到位置,签名的话见:https://www.cnblogs.com/vipsoft/p/18644127 新项目可以尝试一下 iText 7 , 我这边是老项目所以还是继续使用 iText 5,主打够用 iText 5 没有直接提供获取文本精确位置的功能。它只能提取文本内容,而文本位置通常需要通过…