一些关于引用的笔记
目录
引用的概念
‘&’这个符号,对于刚学完C语言的没有接触C++的小白,看到的第一眼就会认为 ,这是个取地址符,或者是与或非的与 但是不同的场景,&所代表的含义不同 例如
int a =1;int b = 0;
int c = a&b; // (1)
int* d = &c; // (2)
int& e = c; // (3)
这里的第一个 & 是与运算符;第二个&是取地址符;而第三个& 则是c++里的引用符;
那么这第三个&,代表的是什么意思呢
这里d保存的是c的地址,打印可以看出 e和c的值相等,不仅如此他们的地址也相等,这相当于e 是c的一个别名,外号,虽然名字不同但表示的是同一个东西;
引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空 间,它和它引用的变量共用同一块内存空间。
类似于’齐天大圣‘,’美猴王‘,’孙悟空‘ 虽然称呼不同,但都表示的同一个事物、
引用的特性
引用的一些特性
1. 引用在定义时必须初始化
2. 一个变量可以有多个引用
3. 引用一旦引用一个实体,再不能引用其他实体
引用在定义的时候必须初始化,否则编译器就会报错、
一个变量可以有多个引用,就跟一个人可以有很多个外号一样
常引用
常引用
引用和指针,在赋值/初始化的时候,权限可以缩小,但是不能放大;
例如这里的 c和*p1,都是由const修饰,是只读的,而对这两个引用取的别名没有const修饰,可以修改,权限放大是不被允许的,要解决问题,就要让他们的权限保持;
那么 ,权限缩小呢?请看下面的例子
在来看看这组例子
在ret前面加了&引用后,为什么编译不过去了呢?
函数func()传值返回,那它返回的值是不是函数里面的n呢,并不是,而是用一个临时变量接收了n的值然后返回的是这个临时变量,而临时变量具有常性;(就跟被const修饰了一样,不能被修改)
所以 这里要保持权限相等,加一个const就可以了;
最后一组例子;
看到这里第一眼可能会疑惑,为甚一个int 类型起了别名变成了double类型了?
这个i到底是int 类型还是double类型?
首先给出答案 这个i 还是int 类型,这种取别名类似于强制类型转换,在强制类型转换的过程中,并不是直接将一个a类型变成了b类型,而是产生了一个b类型的临时变量,将a按b类型的形式放到了这个临时变量里,然后将临时变量赋给b;
所以这里的 double类型的别名m要接收一个临时变量,而刚才又提到过“临时变量具有常性”,所以要在前面加一个const 进行权限保持
使用场景
使用场景
1,做参数
2,做返回值
——做参数
做参数时可以直接传参,在函数内的改变也会改变其本身,就像小明的外号叫张三,张三被打了,小明和张三是同一个人,自然是同样的结果
——做返回值
引用返回(出了作用域,只要没有销毁,就可以使用引用返回)
1,减少拷贝
2,调用者可以修改返回对象
PostAt()函数中return的ay.a[i],在出了函数的作用域之后依然存在,所以这里可以用引用返回int&。
在main函数的第一个for循环中,对每个PosAt的返回值修改,从在第二个for循环打印函数返回值可以看到
另一个例子
这里的Add的返回值 为什么第一个是3,而第二个是随机值呢?
这里的x相当于c这块空间的别名,直接访问x的值可能是3,也有可能是随机值,在出函数调用结束后,栈帧销毁可能会被清理,这里的3可能也是随机值,栈帧还没被清理,后面的add(),则是函数栈帧被清理了,这块空间已经不属于c了,所以是一个随机值。所以出了作用域对象不在了就不要使用引用返回。
如果函数返回时,出了作用域,如果返回对象还在(还没还给系统),则可以使用引用返回,如果已经还给系统了,则必须使用传值返回。