本文首发于个人博客
C++ 引用
- 引用变量是一个别名,也就是说,它是某个已存在变量的另一个名字。一旦把引用初始化为某个变量,就可以使用该引用名称或变量名称来指向变量。
注意点
- 引用相当于是变量的别名(基本数据类型、枚举、结构体、类、指针、数组等,都可以有引用)
- 对引用做计算,就是对引用所指向的变量做计算
- 在定义的时候就必须初始化,一旦指向了某个变量,就不可以再改变,“从一而终”
- 可以利用引用初始化另一个引用,相当于某个变量的多个别名
- 不存在【引用的引用、指向引用的指针、引用数组】
例如
1 | int main(){ |
上面的代码中修改ref也就相当于修改了age。
引用的本质
- 引用的本质就是指针,只是编译器削弱了它的功能,所以引用就是弱化了的指针
- 一个引用占用一个指针的大小
间接证明
1 | struct person { |
在X86位架构下,上面的代码输入为 person size is 4
如果代码改成如下
1 | struct person { |
在X86架构下,上面的代码输入为 person size is 8
而我们知道在X86架构下,指针类型占用字节为8。int 类型为占用4个字节。所以引用和指针占用字节数一样。
汇编证明
- 如下使用指针的代码
1 | int main(){ |
汇编代码如下
1 |
|
- 把指针改成引用的代码
1 |
|
汇编代码如下
1 | _main: |
可发现,引用和指针的汇编代码完全一致。就说明最终转成机器码也是一样的。所以引用的本质就是指针。
常引用(Const Reference)
- 引用可以被const修饰,这样就无法通过引用修改数据了,可以称为常引用
- const必须写在&符号的左边,才能算是常引用
const引用的特点
- 可以指向临时数据(常量、表达式、函数返回值等)
- 可以指向不同类型的数据
- 作为函数参数时(此规则也适用于const指针)
- 可以接受const和非const实参(非const引用,只能接受非const实参)
- 可以跟非const引用构成重载
当常引用指向了不同类型的数据时,会产生临时变量,即引用指向的并不是初始化时的那个变量
常引用指向相同类型的数据
1 | int a = 10; |
上面代码输出为12。其对应的汇编如下
1 | push rbp |
常引用指向不同类型的数据
1 | int a = 10; |
上面代码输出为10。其对应的汇编如下,改变了a的值,并不能改变ref的值
1 | _main: |