• [C++] C++引用如何使用,和指针有何区别


    image.png

    本文来谈谈C++中的引用,引用的出现呢,其实是为了弥补C语言的语法不足,java 等其他语言中都有引用的概念,唯独C没有,我们来往下看

    1.引用概念

    引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空
    间,它和它引用的变量共用同一块内存空间

    有一个很好的例子, 比如大家都玩LOL , 但是它本身叫英雄联盟
    image.png
    比如说他, 有人叫他烬, 有人叫他瘸子,但是说的都是它,引用当前是可以这样理解的

    2.引用使用

    基础语法:

    引用的基础语法是这样使用的

    类型& 引用变量名(就是要起的别名) = 引用实体;

    举个栗子
    image.png

    大家可以看到, a的值和b的值相同,a的地址和b的地址相同
    **所以说在语法层次,b就是a的别名 **

    需要注意的一个问题就是**引用类型必须和引用实体是同种类型的 **
    image.png

    一般编译器报这种红线都是发生了错误

    image.png

    3.引用特性

    引用有好几个特性, 都是非常值得注意的地方

    1. 引用在定义时必须初始化
    2. 一个变量可以有多个引用
    3. 引用一旦引用一个实体,再不能引用其他实体

    其实这几个定义特性都是比较好理解的

    引用在定义时必须初始化

    类比生活中就是,你要给人别人起别名,你总得给知道给谁起吧, 我起个别名, 我不知道我给谁起
    这合理吗
    8f1001e95baa401fa5c718e3d8f51a7.png

    所以引用在定义时一定要初始化
    image.png

    一个变量可以有多个引用

    这个其实也好理解, 比如你家里人会叫的乳名/小名, 你妈妈生气的时候就会大声呼喊你的大名,你对象可能叫你baobao…你舍友可能会给你起各种各样的外号, 但是终究还是你
    image.png

    image.png

    引用一旦引用一个实体,再不能引用其他实体

    这样说吧,你今天管你室友A叫 小黑,明天管室友b叫小黑, 后天管室友c叫小黑, 我感觉你得挨揍,
    我们一般都是起别名都是固定的人的

    image.png
    image.png

    所以可以看到,编译器根本不会管你想要修改引用

    常引用

    引用这里有一个权限的概念,我们来往下看

    假设下面一个场景
    const int a = 0;
    int& b = a;
    大家都知道const修饰一个变量,代表这个变量具有常属性, 是不能修改的,那这样定义引用,是否可以修改呢?
    我们来试一下,
    image.png
    这也正常,肯定是不能修改的,这就是说默认b是a 的引用,声明方式为int不具有常属性, 但是a变量本身是具有常属性的

    这就是变量是不可以修改的,定义的引用也得是不可以修改的,不可以放大权限

    那本身是可以修改的, 可否引用定义为const类型呢
    image.png

    这就是可以缩小权限,但是不可以放大权限

    这样定义的引用自然是不可以修改的,大家可以自己测试一下
    引用的这三个特性都是比较好理解的,不需要记忆,通过引用的定义直接就能判断出来
    引用类型必须和引用实体是同种类型的

    我们来看这样一个例子

    image.png
    但是如果加上一个const , 就可以用了, 这是为什么呢?
    image.png

    首先是表达式会生成一个临时变量, 在表达式结束的时候就会被销毁, 而且临时变量具有常属性, 所以使用const修饰就可以通过编译, 使用const&将临时表达式的寿命延长到表达式末尾之后,生命周期拉长

    引用的使用场景

    1.做参数

    大家现在应该基本理解了引用的基本概念,我们来看看引用作为函数参数有何妙用

    大家一定写过一个函数, 叫做swap ,用来交换两个数
    image.png

    C语言的指针问题,对于不少初学者可以一个大难题, 还记得之前写单链表的时候有一个二级指针的使用,不知道大家会使用了没有,顺序表和链表

    不知道对于大家怎么想, 我觉得能不用指针解决的问题就不用指针解决,指针的出现可能会带来很多错误
    image.png

    如果不小心这样传参, 你是否需要在函数内特殊处理

    但是引用就不会
    image.png

    不过引用到底是怎么实现的,还是和指针相关,而且很多指针能做的,引用做不了,比如链表只用引用就实现不了,大家可以试试

    image.png

    2.引用做返回值

    我们写函数的返回值都是直接返回它的类型,那为什么要用引用返回呢,我们来看看

    image.png

    如果返回的是一个很大的数据呢?? 那么寄存器是存储不下的, 所以调用者就会提前开辟空间来存储

    如果我们使用引用返回
    image.png

    这个代码是存在问题的:

    1. c是Add栈帧中的局部变量,Add调用结束之后就会被释放,所以相当于访问了不属于自己的空间,非法访问
    2. 如果编译器把这块空间给销毁了,那么ret中的值就是随机值,在c语言中,非法读取编译器一般不会报错,如果未清理成随机值,那么看似读取的是正确的,但是本身是错误的

    VS下:
    image.png

    可以看到VS没有把空间清理掉, 但是会爆出警告

    有的朋友可能会说,没有错误,因为结果是正确的,那我们来瞅瞅
    image.png

    这里是用的vs2013, 并没有修改ret,但是确实变化了

    我们在Linux下看一眼, 会不会清理
    image.png

    所以使用引用做返回值,一定要注意的就是,不能返回局部变量
    所以一般引用做返回值都是返回没有被释放的空间, 比如静态的变量OR 动态开辟的空间 ,以及对象

    引用和指针的区别

    引用在语法层面就是起了一个别名,并没有开辟新的空间
    但是底层实现: 是通过指针来实现的

    image.png

    那么引用和指针有什么区别呢???

    1. 引用概念上定义一个变量的别名,指针存储一个变量地址。
    2. 引用在定义时必须初始化,指针没有要求
    3. 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何
      一个同类型实体
    4. 没有NULL引用,但有NULL指针
    5. 在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32
      位平台下占4个字节)
    6. 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小
    7. 有多级指针,但是没有多级引用
    8. 访问实体方式不同,指针需要显式解引用,引用编译器自己处理
    9. 引用比指针使用起来相对更安全

    C++引用就暂时说到这里了,在后面学习到更深度的层次就会更有不一样的理解了,目前我只理解到地方啦,大家有问题可以私我一起交流
    感谢收看

    image.png

  • 相关阅读:
    3款windows实用软件,免费又良心,真正懂你的需求
    ipv6检测易语言代码
    Typescript类功能混合(mixin)使用,将多个类中功能合并到一个对象
    JavaWeb实现smbms项目核心功能
    二、TensorFlow结构分析(1)
    【canvas】-- H5新增标签canvas的简单用法
    使用腾讯云轻量服务器安装AList
    中台架构介绍和应用价值
    基于机器视觉的图像处理缺陷检测方法论文学习
    List 实现
  • 原文地址:https://blog.csdn.net/weixin_54580407/article/details/127818567