zoukankan      html  css  js  c++  java
  • C++中的引用到底是什么

    这也算是一个老生常谈的问题,写这个其实就是想趁着暑假把博客丰富一下。

    咱随便在谷哥、度娘、病软引擎上搜搜都可以得到各种关于引用的解释,无非就是“引用不同于指针,引用是一个变量的别名”“使用引用就是使用变量本身”“”等等这些,于是大量的概念轰炸下,“引用不占用空间”这一言论貌似也是到处都有,流传甚广,几近泛滥,已经有淹没真想之势。于是本着追逐真理之精神,把引用究竟占不占空间这事儿解释清楚,至于引用与指针是不是不同的东西,这一哲学问题见仁见智,咱们就不去探究,真想搞清楚还是得问C++的爸爸。

    真要搞清楚,还得从代码本身出发。

    int main()
    {
        int a=10;
        int* b=&a;
        a=30;
        *b=20;
    }

    先看看这段代码有什么意义?是不是觉得没有什么意义?嗯,确实没什么意义,从表面上也完全看不出什么来,当然了,如果您看出什么来了,那您一定要当什么都没看出来!

    好了,要想知道这段代码做了什么,还得从汇编看起,毕竟从底层看起能都尽量多地绕过编译器,展示其真实行为,不失为一个学习基本概念的好办法。因为我用的是linux平台,所以我比较倾向于用AT&T汇编展示,如果您不熟悉,完全没关系,赶紧关掉网页,麻溜走人!。。。。。英雄留步,我这儿跟你开个玩笑活跃一下气氛,诶,诶,那位爷,能别抄起凳子么?

    subl    $16, %esp    //分配空间
        call    ___main     
        movl    $10, 8(%esp)   //把10存入变量a代表的空间
        leal    8(%esp), %eax  //将变量a的地址存入寄存器eax
        movl    %eax, 12(%esp)  //将变量a的地址存入另一块儿地址,这里即指针b
        movl    $30, 8(%esp)    //将30赋值给变量a
        movl    12(%esp), %eax  //将变量a的地址赋值给寄存器eax
        movl    $20, (%eax)     //将20赋值给寄存器eax的值所代表的地址处,

    通过注释(应该还算清晰吧),可以完整对应上面那段代码的行为,这里可以真切地从肌肤与体位上感受到其行为的确定性。可以看到,一切都在我们的掌控之中。

    下面对代码进行一点小修改:

    int main()
    {
        int a=10;
        int& b=a;
        a=30;
        b=20;
    }

    经过对比,可以看到,仅仅是将指针换成了引用,嗯,从语义上看,其行为貌似发现了一些变化,但是在内部发生了什么呢?您请往下走:

    subl    $16, %esp
        call    ___main
        movl    $10, 8(%esp)
        leal    8(%esp), %eax
        movl    %eax, 12(%esp)
        movl    $30, 8(%esp)
        movl    12(%esp), %eax
        movl    $20, (%eax)

    なに!代码发生了什么变化?您看出变化来了吗?如果您看出来了,出门儿右拐大药房滴眼液来两滴。

    可以看到汇编层面上,其行为没有任何变化,与指针是一模一样的,咱们就此打住,不用多想,指针要占用4字节的空间,您引用既然和指针是同样的东西,凭什么不占?嗯,其实就这么点事儿。

  • 相关阅读:
    Jenkins解决Host key verification failed
    jenkins+gitlab发布maven项目
    gitlab升级、汉化、修改root密码
    jenkins发布普通项目、配置自动上线自动部署
    Jenkins安装配置
    awk在企业中最常用的语句
    OpenLDAP给我的启发
    三观很正的一些话
    一次完整的http请求过程以及网络I/O模型select、epoll
    Nginx三种模式的虚拟主机(附Apache基于域名的虚拟主机)
  • 原文地址:https://www.cnblogs.com/imjch/p/3902967.html
Copyright © 2011-2022 走看看