C++ 学习 关于引用
🙋本文主要讲讲C++的引用 是基础入门篇~
🌈 关于引用 几个比较重要的点
🌿引用相当于为一个已经存在的对象所起的另外一个名字
🌞 定义引用时,程序把引用和它的初始值绑定(bind)在一起,而不是将初始值拷贝给引用。一旦初始化完成,引用将和它的初始值对象一直绑定在一起。因为无法令引用重新绑定到另外一个对象,因此引用必须初始化
🌺 另外要注意 类型不能混用
🐳相信看完后 你会有所收获~
⛵
- 引用并非对象
- 引用必须初始化
- 引用只能绑定在对象上,而不能与字面值或某个表达式的计算结果绑定在一起
- 类型要严格匹配
引用
C++11中新增了一种引用:所谓的“右值引用(rvalue reference)”,我们将在13.6.1节(第471页)做更详细的介绍。这种引用主要用于内置类。严格来说,当我们使用术语“引用(reference)”时,指的其实是“左值引用(Ivaluereference)”。
引用(reference)为对象起了另外一个名字,引用类型引用(refers to)另外一种类型。通过将声明符写成&d的形式来定义引用类型,其中d是声明的变量名:
1 | int ival =1024; |
一般在初始化变量时,初始值会被拷贝到新建的对象中。然而定义引用时,程序把引用和它的初始值绑定(bind)在一起,而不是将初始值拷贝给引用。一旦初始化完成,引用将和它的初始值对象一直绑定在一起。因为无法令引用重新绑定到另外一个对象,因此引用必须初始化。
引用并非对象,相反的,它只是为一个已经存在的对象所起的另外一个名字。
定义了一个引用之后,对其进行的所有操作都是在与之绑定的对象上进行的:
1 | refval = 2; |
为引用赋值,实际上是把值赋给了与引用绑定的对象。获取引用的值,实际上是获取了与引用绑定的对象的值。同理,以引用作为初始值,实际上是以与引用绑定的对象作为初始值:
1 | //正确: refval3绑定到了那个与refval绑定的对象上,这里就是绑定到ival上 |
因为引用本身不是一个对象,所以不能定义引用的引用。
引用的定义
允许在一条语句中定义多个引用,其中每个引用标识符都必须以符号&开头:
1 | int i =1024,i2 =2048;// i和i2都是int |
除了2.4.1节(第55页)和15.2.3节(第534页)将要介绍的两种例外情况,其他所有引用的类型都要和与之绑定的对象严格匹配。而且,引用只能绑定在对象上,而不能与字面值或某个表达式的计算结果绑定在一起,相关原因将在2.4.1节详述:
1 | int &refVal4 = 10; |
练习
👊 检验一下成果叭~
1 | //练习2.15:下面的哪个定义是不合法的?为什么? |
🌿答案答案
//练习2.15:下面的哪个定义是不合法的?为什么?
int ival = 1.01;
是不合法的。因为int
类型只能存储整数,不能存储浮点数1.01
。int &rval1 = 1;
是不合法的。因为1
是一个字面量,它代表了整数1,但字面量不能被直接赋值给引用。而且,引用的定义需要一个已存在的变量作为其目标。int &rval2 = ival;
是合法的,假设ival
已经正确定义并且是一个int
类型的变量。int &rval3;
是合法的,但rval3
未被初始化,它将包含未定义的值。
练习2.16:考查下面的所有赋值然后回答:哪些赋值是不合法的?为什么?哪些赋值是合法的?它们执行了什么样的操作?
r2 = 3.14159;
是合法的。它将double
类型的字面量3.14159
赋值给r2
,r2
是一个double
类型的引用。r2 = rl;
是不合法的。因为rl
是一个int
类型的引用,而r2
是一个double
类型的引用。类型不匹配。i = r2;
是不合法的。因为i
是一个int
类型的变量,而r2
是一个double
类型的引用。尝试将一个double
类型的值赋给一个int
类型的变量会导致数据丢失。rl = d;
是合法的,但可能导致数据丢失。因为rl
是一个int
类型的引用,而d
是一个double
类型的值。int
类型不能准确表示double
类型的值,所以只有d
的整数部分会被存储在rl
指向的int
类型变量中。
练习2.17:执行下面的代码段将输出什么结果?
虽然i
的值被5
所赋值,随后ri
被赋值为10
,但std::cout
会输出i
和ri
当前的值(不是所赋的值),此时i
由于ri
的赋值操作而覆盖了原本的值,ri
输出为10
。引用只是为其他变量提供了一个别名,并不复制原变量的值。所以i
也是10