| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> C++知识库 -> 【C++】C++ 引用 -> 正文阅读 |
|
[C++知识库]【C++】C++ 引用 |
一、引用的概念在我们的现实生活中,一个人经常不只一个名字,比如一个人叫张三,那么在家里,它的父母可能喊他老三,在学校/公司,由于他本身性格或其他方面的一些特征,他可能又有别的外号;在古代,这种情况极为正常,比如宋江又叫及时雨,李逵又叫黑旋风、铁牛,鲁迅又叫周树人等等;我们把上面这些外号/亲称叫做别名。 而引用就是给一个已经存在的变量取别名:引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。 引用的符号和我们C语言中取地址的符号一样,为 &;在某类型名的后面加上引用符号 (&) 就变为了引用类型。设计引用的目的是简化指针的使用,但是引用不能代替指针 (实际上引用的底层是用指针实现的)。
注意:引用类型必须和引用实体是同种类型的。 二、引用的特性引用有如下特性:
三、常引用常引用就是在引用类型前面用 const 来进行修饰;和 const 修饰变量一样,被 cosnt 修饰的引用只能够读,而不能够写,即不能修改引用变量的值; 对于常引用来说,另外一个重要的知识点就是引用的权限问题 – 权限只能被缩小,不能被放大; 注: 这里的权限指的是读和写的权限,且只针对于指针和引用。 下面我们来看一些引用的例子: 常规引用:
对常量的引用:
在C语言的学习中,我们知道可以用一个变量的地址对指针进行初始化,也可以直接赋给指针一个地址;那么对于引用来说,出来对变量进行引用,我们是否也可以对常量进行引用呢?答案是:可以,只是有一些限制条件。
对不同类型的变量进行引用:
和对常量进行引用类似,当我们的引用类型和变量类型不同时,该变量会先被赋值给一个与引用同类型的临时变量;在上面的例子中,由于引用类型是 int&,而变量类型是 double,二者不相同,所以对 b 进行引用时,b 会被先转化为 int 类型,然后赋值给一个临时变量,然后我们对这个临时变量进行引用;后面的内容就和常引用相同了,由于临时变量具有常性,所以我们需要用 const 修饰 int&,防止权限扩大。 注:常引用以后会频繁出现在我们的函数参数中,非常重要。 四、引用的使用场景1、引用做参数引用做参数的两个实例:
引用做函数参数的优点
常引用做参数 现在我们知道了引用做参数可以提高效率以及直接改变实参,那么如果我们只想提高效率可不可以用引用呢?比如,我们想要打印一个非常大的结构体中的数据,如果用一般参数,那么形参拷贝的消耗就很大;但如果我们用引用,虽然提高了效率,但原数据的安全性又得不到保证 (可以在打印函数中修改结构体中的数据);而常引用的特性正好可以解决这个问题;实际上在C++中,一般非输出型参数都是常引用参数。 2、引用做返回值一般参数返回
在 函数栈帧的创建和销毁 中我们知道:调用函数要开辟栈帧,函数栈帧是在栈区上开辟的,并且当我们调用完毕时该函数栈帧会自动销毁;同时函数中的各种局部变量以及函数形参都是在函数栈帧中分配空间的,所以当我们离开函数范围后再去访问函数中的局部变量,编译器就会报错。 那么,我们自然也不可能去访问被调函数的函数栈帧中寻找函数的返回值 (被调函数的函数栈帧已经销毁),实际上,函数的返回值会先被拷贝到一个临时变量中 (引用做返回值引用的就是这个临时变量),如果返回值较小,比如四个字节,那么临时变量就由寄存器充当;如果函数的返回值较大,比如是一个结构体,那么就由调用此函数的函数在其自身函数栈帧中开辟一块空间来充当临时变量。 在上面这段代码中,由于 n 是局部变量,函数调用完毕空间销毁,所以我们返回的是保存函数返回值的局部变量的值,而不是 n 的值。 在明白了这些之后,我们来看下面两个代码段: 代码段1:
代码段2:(注:下面对引用的使用方式是错误的,但是我们需要知道它为什么错了)
要想理解上面这段代码,我们需要知道函数栈帧销毁的本质是什么? 函数栈帧的销毁并不是说真的就将那块空间给销毁了,而是代表该栈帧空间中的数据不受保护了,即该空间中的数据可能被进行如下操作:
现在我们再回过头来看上面这段代码:
总结::如果函数返回时,出了函数作用域,如果返回对象还在(还没还给系统),就可以使用引用返回,如果已经还给系统了,则必须使用传值返回。 引用做返回值的优点
五、性能比较1、传值、传引用性能比较以值作为参数或者返回值类型,在传参和返回期间,函数不会直接传递实参或者将变量本身直接返回,而是传递实参或者返回变量的一份临时的拷贝,因此用值作为参数或者返回值类型,效 率是非常低下的,尤其是当参数或者返回值类型非常大时,效率就更低。
2、值和引用作为返回值的性能比较
通过上述代码的比较,你会发现传值和指针在作为传参以及返回值类型上效率相差是很大的。 六、引用和指针的区别语法概念上:引用就是一个别名,没有独立空间,和其引用实体共用同一块空间。
底层实现上:引用实际是有空间的,因为引用是按照指针方式来实现的。
我们调试代码,然后转到反汇编后可以发现,引用和指针的汇编代码是完全一样的,即引用的底层实际上就是指针。 引用和指针的不同点
|
|
C++知识库 最新文章 |
【C++】友元、嵌套类、异常、RTTI、类型转换 |
通讯录的思路与实现(C语言) |
C++PrimerPlus 第七章 函数-C++的编程模块( |
Problem C: 算法9-9~9-12:平衡二叉树的基本 |
MSVC C++ UTF-8编程 |
C++进阶 多态原理 |
简单string类c++实现 |
我的年度总结 |
【C语言】以深厚地基筑伟岸高楼-基础篇(六 |
c语言常见错误合集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/23 10:18:37- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |