• C++ “引用”究竟是什么?(代码实测)


            C++的引用是个挺好用的东西,相当于指针的另一种写法,虽然引用有一些约束,比如必须初始化而且不能修改引用目标,但确实非常大地增加了编程的清晰度和灵活性。

    目录

    一、引用的价值

    二、引用的隐患

    三、代码实测


    一、引用的价值

            引用主要有这些价值:

    1. 简化指针访问,“.”比“->”少一个字符,而且更容易理解
    2. 使指向指针的指针更容易理解,“int * &”比“int **”容易理解多了
    3. 函数传参和重构灵活,可以通过重新定义参数来轻易地在指针和引用之间转换,避免对整个代码进行“.”和“->”的替换。

    二、引用的隐患

            当然,凡事有利就有弊,引用本质是个指针,那么就是两个本质相同的东西拥有不同的表达方式,必然会带来一点混乱。

            比如一个以前是“int”类型的参数,现在被改成了“int &”并且在函数里面修改了值,那么原来的程序会出错,而编译器不会发现任何问题。当然,严格地说,这是函数修改者的错误,这种改变接口的行为的变更是不可以轻易进行的,可是事实却是调用者的代码无辜出错了。

    三、代码实测

            以上是理论,现在我们用代码看看引用到底是什么:

    1. #include
    2. #include
    3. void f(int& x)
    4. {
    5. printf("-------------------------------\n");
    6. printf("sizeof(x) : %2zd : typeid : %s\n", sizeof(x), typeid(x).name());
    7. printf("%p %d\n", &x, x);
    8. }
    9. void f2(int* x)
    10. {
    11. printf("-------------------------------\n");
    12. printf("sizeof(x) : %2zd : typeid : %s\n", sizeof(x), typeid(x).name());
    13. printf("%p %p\n", &x, x);
    14. }
    15. int main()
    16. {
    17. int a = 111;
    18. printf("a %p %d\n", &a, a);
    19. int& r_a = a;
    20. printf("r_a %p %d\n", &r_a, r_a);
    21. int* p_a = &a;
    22. printf("p_a %p %p\n", &p_a, p_a);
    23. f(a);
    24. f(r_a);
    25. f(*p_a);
    26. f2(&a);
    27. f2(&r_a);
    28. f2(p_a);
    29. return 0;
    30. }

            这是VS2022的64位C++控制台程序代码(debug版),在main函数任何一处设置断点,调试运行,在程序运行到断点处停下来之后,打开反汇编窗口,看看反汇编代码的样子:

            两个红色方框出的代码分别是给引用和指针赋值,即使完全不懂汇编也能看出来——毫无区别。

            下面是调用"f(int&x)"的反汇编代码:

            “f(r_a)”和“f(*p_a)”的汇编代码相同是能看出来的。

            下面是调用“f2(int* x)”的反汇编代码:

            看得出来,跟前面的一样啊,这就很明白了,“引用”其实就是“指针”,不过语法上被当作“别名”,我们看一下这个程序的输出:

            红线指向的就是“f(int &x)”的参数类型,分明写着“int”啊,所以“引用”在语法层面是“别名”,内部实现为指针。

    (这里是结束)

  • 相关阅读:
    jenkins: pass multiple “Extended Choice Parameter“ values using a URL
    计算机毕业设计django基于python租房系统-房屋租赁系统(源码+系统+mysql数据库+Lw文档)
    DayDreamInGIS 逆地理编码工具(根据经纬度获取位置描述)插件源码解析
    发国际快递美国专线需要注意什么事项
    uni.getLocation() 微信小程序 线上获取失败
    前端怎么对表单进行正则 前端常用的校验属性
    C++ Crow web框架使用;升级cmake ;pthread、boost、asio 报错
    安卓案例:学生信息管理
    Vue输入框卡死
    如何翻译图片上的英文?建议收藏这三个方法
  • 原文地址:https://blog.csdn.net/2301_77171572/article/details/133899579