1、引用的定义
引用是给一个已经定义过的变量重新起的别名,对其操作时相当于对变量直接进行操作;编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。
就类似于小时候别人给你起的外号。
定义格式:
int a=10;
int &b=a;
2、引用的特点
- 引用在定义时必须被初始化。
- 一个变量可以有多个引用。
- 引用一旦绑定了一个实体,就不能在改变为其他变量的引用。
3、常引用(const引用)
void Test(){
int iNum0=10;
const int &iNum1=iNum0;
}
常引用特点:
- 不能给常引用变量赋值。
- const修饰的引用变量会具有常属性。
- 具有常属性的变量不能直接被引用,需要常引用来引用。
- 不同类型进行引用赋值时,会借助临时变量完成操作,也需使用常引用进行引用(不能给不同类型的引用赋值,例如将一个double类型的变量d赋值给一个int类型的引用i,就不能编译通过。因为赋值时会生成一个临时变量。d引用的是这个带有常性的临时变量,所以不能赋值)。
4、引用的使用场景
4.1 作为函数形参传递
- 函数调用时,不想使用指针改变形参从而改变实参的值,可使用引用直接对形参进行改变
- 函数调用时,如果不需要改变参数的值,尽量使用常引用作为参数,以此提高效率
- 值传递:如果形参为非引用的传值方式,则生成局部临时变量接收实参的值。
- 引用传值:如果形参为引用类型,则形参是实参的别名(当不希望函数内改变参数x的地址时,尽量采用常引用传参)。
- 指针传参:如果形参为指针类型,则生成匿名对象接收地址。
4.2 作为函数返回值传递
- 引用做返回值时,将返回变量的地址存放到寄存器当中。
- 如果一个函数返回了引用,那么该函数的调用也可以被赋值。
- 不要返回一个临时变量的引用。
- 如果返回对象出了当前函数的作用域依旧存在,则最好使用引用返回,因为这样更高效。
- 注意不要返回栈内存的引用。
5、引用和指针的区别
相同点:
- 底层的实现方式相同,都是按照指针的方式来实现。
不同点:
- 引用在定义时必须被初始化,指针则可以不用,但正常情况下指针需初始化为NULL。
- 引用一旦被定义,就不可以再改变引用别的变量,而指针还可以在指向别的变量。
- sizeof引用得到的是所指向变量的大小,sizeof指针时得到的是所指向对象地址的大小。
- 自增自减操作含义不同:引用自增自减改变的是变量的值,指针自增改变的是指针所指向对象的地址自加自减一个类型大小。
6、引用总结
- 引用在定义时必须被初始化,指针没有要求。
- 一旦一个引用被初始化为指向一个对象,就不能再指向其他对象,而指针可以在任何时候指向任何一个同类型的对象。
- 没有NULL引用,但有NULL指针。
- 在sizeof中含义不同,引用结果为引用类型的大小,指针结果始终是地址空间所占字节个数。
- 引用自加改变变量的内容,指针自加改变了指针指向。
- 有多级指针,但是没有多级引用。
- 指针需要手动寻址,引用通过编译器实现寻址。
- 引用比指针使用起来相对更安全。