深入分析C++引用

深入分析C++引用

大家好,又见面了,我是全栈君,祝每个程序员都可以多学几门语言。

      关于引用和指针的差别的文章非常多非常多,可是总是找不到他们的根本差别,偶然在codeproject上看到这篇文章,认为讲的挺好的,

所以翻译了下,希望对大家有帮助。

原文地址: http://www.codeproject.com/KB/cpp/References_in_c__.aspx

 

引言

      我选择写 C++ 中的引用是由于我感觉大多数人误解了引用。而我之所以有这个感受是由于我主持过非常多 C++ 的面试,而且我非常少从面试者中得到关于 C++ 引用的正确答案。

       那么 c++ 中引用究竟意味这什么呢?通常一个引用让人想到是一个引用的变量的别名,而我讨厌将 c++ 中引用定义为变量的别名。这篇文章中,我将尽量解释清楚, c++ 中根本就没有什么叫做别名的东东。

 

背景

c/c++ 中,訪问一个变量仅仅能通过两种方式被訪问,传递,或者查询。这两种方式是:

1. 通过值 訪问 / 传递变量

2. 通过地址 訪问 / 传递变量 这样的方法就是指针

 

       除此之外没有第三种訪问和传递变量值的方法。引用变量也就是个指针变量,它也拥有内存空间。最关键的是引用是一种会被编译器自己主动解引用的指针。非常难相信么?让我们来看看吧。。。

 

以下是一段使用引用的简单 c++ 代码

 

 

引用事实上就是 c++ 中的常量指针。表达式   int &i = j; 将会被编译器转化成 int *const i = &j; 而引用之所以要初始化是由于 const 类型变量必须初始化,这个指针也必须有所指。以下我们再次聚焦到上面这段代码,并使用编译器的那套语法将引用替换掉。

 

 

    读者一定非常奇怪为什么我上面这段代码会跳过打印地址这步。这里须要一些解释。由于引用变量时会被编译器自己主动解引用的,那么一个诸如   cout << &j << endl; 的语句,编译器就会将其转化成语句   cout << &*j << endl;   如今 &* 会相互抵消,这句话变的毫无意义,而 cout 打印的 j 值就是 i 的地址,由于其定义语句为 int *const j = &i;

 

      所以语句 cout << &i << &j << endl; 变成了 cout << &i << &*j << endl; 这两种情况都是打印输出 i 的地址。这就是当我们打印普通变量和引用变量的时候会输出同样地址的原因。

 

      以下给出一段复杂一些的代码,来看看引用在级联 (cascading) 中是怎样运作的。

 

 

以下这段代码是将上面代码中的引用替换之后代码,也就是说明我们不依赖编译器的自己主动替换功能,手动进行替换也能达到同样的目标。

 

 

         我们通过以下代码能够证明 c++ 的引用不是神马别名,它也会占用内存空间的。

 

 

结论

我希望这篇文章能把 c++ 引用的全部东东都解释清楚,然而我要指出的是 c++ 标准并没有解释编译器怎样实现引用的行为。所以实现取决于编译器,而大多数情况下就是将事实上现为一个 const 指针。

 

 

引用支持 c++ 虚函数机制的代码

 

 

 

上述代码使用引用支持虚函数机制。假设引用不过一个别名,那怎样实现虚函数机制,而虚函数机制所须要的动态信息只能通过指针才干实现,所以更加说明引用事实上就是一个 const 指针。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/118717.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • linux分区及格式_ubuntu安装系统分区

    linux分区及格式_ubuntu安装系统分区操作环境:vmware虚机一、整体流程在使用fdisk/parted等分区工具对硬盘分区之后,是否使用LVM由用户决定: 1)可以直接对分区后的硬盘进行格式化操作,之后挂载分区; 2)也可以先用LVM逻辑卷管理工具对分区后的物理卷进行管理,之后再对逻辑卷进行格式化操作,之后挂载分区。(LVM的分区类型为8e) 使用LVM的好处是方

    2025年6月12日
    3
  • uniapp中使用jsencrypt进行RSA加密,解决密文作为参数传输到后台时+号变成空格的问题「建议收藏」

    uniapp中使用jsencrypt进行RSA加密,解决密文作为参数传输到后台时+号变成空格的问题「建议收藏」解决密文作为参数传输到后台时+号变成空格的问题用encrypt.encrypt()加密后生成的密文字符串中带有加号,如下Q3Q+ZijLMjcKyC1whAzxtfVpy7G+N1kpCGQJYO8dISQ1UyEzczC6vdqbwG18K6ylTv2fXujogOFwzgZlNuVTKEDVeHqjnsYjDcOUJqvE8t8Mxug+vVMnAOsJfzL0eZqYREoq7YoDJ150q7xZB/8XZEfzwnc/4MwKJLHshj+UFCc=密文作为参数传输到后端时+号变成了空格,

    2025年9月7日
    4
  • Pandas DataFrame的基本属性详解

    Pandas DataFrame的基本属性详解PandasDataFrame的一些基本属性基本功能列表importpandasaspd导入库df=pd.DataFrame(data=None,index=None,columns=None,dtype=None,copy=False)创建一个DataFramedf.indexdf.columnsdf.axesdf.Tdf.info()…

    2022年5月5日
    285
  • Python和Java到底有什么区别?

    Python和Java到底有什么区别?转自:微点阅读(www.weidianyuedu.com)微点阅读-范文大全-免费学习知识的网站好多初学编程的小伙伴在问:“Python和Java到底有什么区别?到底是学Python还是Java。“一副惆怅的样子,难以下手。今天,给大家总结了关于两者的十二点区别。一、实话实话,Python虚拟机没有java强,java虚拟机是java的核心Python的核心是可以很方便地使用c语言函数或c++库。二、Python是全动态性的可以在运行时自己修改自己的代码,java只能

    2022年7月7日
    21
  • byte类型取值范围以及溢出详解

    byte类型取值范围以及溢出详解例1:publicclasstest{ publicstaticvoidmain(String[]args){ bytea=127; a=(byte)(a+3); System.out.println(a); }}输出-126,为什么呢byte类型的取值范围是-128-127这个输出结果是由java编码方式决定的,Java中正数用原码

    2022年6月18日
    46
  • [随笔] IE8Beta2 的标准是不是太高了!

    [随笔] IE8Beta2 的标准是不是太高了!昨天安装了ie8beta2,发现网上支付都无法操作。支付宝无法使用。切换兼容模式也没有效果。各位高手有知道怎么回事的吗?请指教!!!!!转载于:https://www.cnblogs.com/zangdalei/archive/2008/08/29/1279160.html…

    2025年7月18日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号