首页 > 其他分享 >引用的全面理解

引用的全面理解

时间:2022-10-13 12:07:02浏览次数:50  
标签:const int 绑定 理解 引用 全面 指针 ra


什么是引用?

引用是在C++2.0版本引入的。

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

一般情况,引用具有以下性质。

  • 1.引用不是一个变量,只是一个已存在变量的别名。
int a = 10;  
int& ra = a;//ra是a的引用
//sizeof(ra) == sizeof(a)
ra = 20;//对ra操作赋值,则相当于对a赋值。
  • 2.可以有多个引用与同一个已存在变量绑定到一起。
int a = 10;  
int& ra1 = a;
int& ra2 = a;
int& ra3 = a;//ra1,ra2,ra3都是a的别名
  • 3.引用不是一个变量,不能定义引用的引用,不能定义指向引用的指针
int& rra = ra;//错误。  
int *p = ra;//错误
  • 4.由于要和某一变量绑定,所以引用必须初始化。
int& ra;// error C2530: “ra”: 必须初始化引用  
  • 5.引用的类型要和与之绑定的变量类型严格匹配。
int a = 10;  
float& fa = a;//error C2440: “初始化”: 无法从“int”转换为“float &”
  • 6.引用绑定后,将一直与变量绑定在一起,所以引用不能再重新绑定到另一变量。
int a = 10;  
int b = 20;
int& ra = a;
&ra = b;//错误,无法重新绑定

注:数组可以引用,只是写法和一般不同

int b[10] = {0};  
int (&rb)[10] = b;

Const的引用

引用除了可以和变量绑定外,还可以绑定到const对象上,称之为“对常量的引用”。所以,对常量的引用,不能修改它所绑定的对象。

提示:常量引用是其实对const的引用,因为引用本身不是一个对象。

const int a = 10;  
const int& ra = a;//对const修饰的变量a的引用
ra = 20;//错误,ra试图修改与它绑定对象的值。
int& ra2 = a;//错误,试图让一个非常量引用绑定到一个常量上。

前面提到,引用的类型必须和其绑定对象的类型一致,但是,C++允许一个常量引用绑定到非常量的对象、字面值,甚至是一个表达式。

int a = 10;  
const int b = 20;

const int& ra = a;//允许将const int&绑定到一个普通int对象上
const int& rb = b;//rb是一个常量引用。

const int& r1 = ra*rb;//r1是一个常量引用
int& r2 = r1*3;//错误:r2是一个非常量引用。

为什么会出现上面的特例呢?
观察下列代码,判断编译器对于i1和i2的理解。

double d = 20.0; int& i1 = d;//error C2440: “初始化”:
无法从“double”转换为“int &” const int& i2 = d;//warning C4244: “初始化”:
从“double”转换到“constint”,可能丢失数据

分析:

第一句话,错误提示:无法从double转换为int &,我们都理解,是因为类型不同。

但是第二句话,不是错误提示:无法从double转换为const int &呢?确实警告double转换为const int有数据丢失。

说明,编译器帮我做了隐式转化,将double转化为const int,然后等号左右两类型相同,自然通过编译。

转化过程:这里编译器对代码进行插手了,为了确保让i2绑定到一个整型,编译器隐式转化,用double类型d 生成了一个临时对象const
int,(临时对象具有常性)。将r2指向了临时对象。

对const的引用可能引用一个非const对象。此时可以通过特殊手段改变const引用的值。

int a = 10;  
const int& ra1 = a;//常量引用
int& ra2 = a;//非常量引用

ra1 = 20;//错误,无法修改
ra2 = 20;//正确,可以修改

引用作为参数或返回值

对引用的操作就是对其绑定对象的操作,所以引用可以作为参数或返回值。

引用作为参数和返回值具有和指针一样的效率但是比指针更安全,操作更方便。

原因下面描述。

引用和指针的区别

想到搞清楚引用与指针的区别,要先看看编译器是如何看待他俩的工作原理

#include <iostream>  

int main()
{
int a = 10;
int& ra = a;
int* pa = &a;

return 0;
}

看其汇编

a;  
012D13C5 lea eax,[a]
012D13C8 mov dword ptr [ra],eax
int* pa = &a;
012D13CB lea eax,[a]
012D13CE mov dword ptr [pa],eax

可以发现,编译器对指针和引用的看待方式相同,即引用被当做指针来看待。 所以:我们一般将int& ra = a与nt *const ra =
a;是等效的。

虽然两者在底层上的实现是相同的,都是当做指针来使用。

但是,在语言层面两者还是有很大的不同。

根据对引用的描述和指针的概念比较可以的出以下结论

  • 1、引用在定义时必须初始化,指针没有要求。
  • 2、一旦一个引用被初始化为指向一个对象,就不能再指向其他对象,而指针可以在任何时候指向任何一个同类型对象
  • 3、没有NULL引用,但有NULL指针。
  • 4、在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数。
  • 5、引用自加改变变量的内容,指针自加改变了指针指向
  • 6、有多级指针,但是没有多级引用
  • 7、引用比指针使用起来相对更安全

    ​​​​​​


标签:const,int,绑定,理解,引用,全面,指针,ra
From: https://blog.51cto.com/u_12704841/5753043

相关文章

  • 140万奖金!目标检测、深度估计、3D点云感知等赛事全面启动!国家智能网联汽车创新中心第
    140万奖金!国家智能网联汽车创新中心第二批ICV创新算法攻关任务全面开启!国家智能网联汽车创新中心作为汽车领域重要的国家智库,旨在突破关键共性技术、搭建创新服务平台。创新......
  • 焦距,光圈,景深以及最短对焦距离的原理解释
    NaN_2019年05月22日 作为一只甚至还没有自己的相机的摄影小白,在 @yggd 的撺掇之下看完果核的这篇入门文章后,终于对一些摄影中基本的术语有了了解......
  • Java查漏补缺——四种引用
    今天复习到一种没看到过的Java知识点,是关于内存不足时Java对象的建立的。引用Java对每一个对象的使用被称为Java的引用,类似于C和C++的指针,引用则是调用对象和对象方......
  • OPC UA 理解
    一些理解OPCUA官方内容OPCUA规范:https://reference.opcfoundation.org/内容太多,很繁琐,还分好多部分。感觉看看配的图片就行了。可以不使用OPCUA这种方式连接吗?是......
  • 03、如何理解Kafka和Zookeeper的关系
    001、Kafka简介ApacheKafka最早是由Linkedin公司开发,后来捐献给了Apack基金会。Kafka被官方定义为分布式流式处理平台,因为具备高吞吐、可持久化、可水平扩展等特性而被......
  • KMP算法中对于next数组构建的理解
     时间:2022/10/12 一.next数组原理的说明KMP算法一般用于解决字符串匹配的问题,在KMP算法出现之前,字符串匹配一般通过双层for循环的暴力方法解决,时间复杂度为O(......
  • C#中值传递和引用传递
      一.传递的概念  传递是指在调用方法时,用实际参数为方法的形式参数赋值。方法的形式参数,按照参数类型划分有两种,分为是值类型和引用类型。  二.数据类型......
  • 《深入理解计算机系统》习题2.61
    #include<stdio.h>intfunction(inta)//此函数返回某个数的补码中最高字节位全为0,或者最低字节位全为1的数。{ intshift=(sizeof(int)-1)<<3; //最低字节位都应是1 ......
  • JavaScript闭包的深入理解
    闭包算是javascript中一个比较难理解的概念,想要深入理解闭包的原理,首先需要搞清楚其他几个概念:一、栈内存和堆内存学过C/C++的同学可能知道,计算机系统将内存分为栈和堆两部......
  • maven 引用本地文件不需要安装本地仓库方式
    <dependency><groupId>com.ctop.crypt</groupId><artifactId>sm</artifactId><version>1.0</version><scope>system</scope><systemPath>${pom.basedi......