C++:引用详解
引用
- 类型后紧跟&->int& b = c;
- 引用是给一个已存在变量取别名,操作的还是原变量空间里的数据;
- 使用规则:
- 引用定义时必须初始化;
- 一旦引用一个实体,就不能再引用其他实体;
- 一个实体可以进行多个引用;
#include<iostream>
using namespace std;
int main(){
int a = 10;
int& b = a;
int& c = b;
b =20;
c = 30;
return 0;
}
const引用
- 常引用-权限只可越来越小,不可比原来权限大;
#include<iostream>
using namespace std;
int main(){
int c = 30;
int e =10;
double&f = e;//编译器报错;
const double&f = e;//编译通过;
return 0;
}
- 因为这里e和f的类型不相同,所以在赋值时要发生隐式类型转换,此时需要由编译器创建一个临时空间存储转换后的e,我们知道,临时变量具有常性,故只可读不可写,所以double&f = e;时等于扩大了权限,编译器会报错,而加上const时f与e的权限正好一样;
引用做参数/返回值
#include<iostream>
using namespace std;
int TestRefReturn(int a){
a+=10;
return a;
}
int& TestRefReturn(int& a){
a+=10;
return a;
}
int main(){
int x = 10;
int y = TestRefReturn(x);
return 0;
}
这里第一个函数是普通的参数和返回值设置,即用什么拿什么接收;这样的话在传入参数和返回参数时,都会先创建一个临时拷贝,再进行操作,如果是一个结构体,会产生极大的浪费,而第二个函数在参数和返回类型上都是引用,根据引用的特性,这样的话便不再产生临时变量,极大提升性能;
但在这种情况下,就会出问题了:
int& Add(int a,int b){
int c = a+b;
return c;
}
int main(){
int& ret = Add(1,2);
Add(3,4);
cout<<"Add(1,2) is :"<<ret<<endl;
return 0;
}//运行结果是随机值;
注意:如果函数返回时,离开函数作用域后,其栈上的空间已经还给系统,因此不能再使用站上的空间作为引用类型返回,因此,不能返回当前函数的局部变量的引用(返回值的生命周期必须比函数生命周期长的时候才能用引用类型返回)
引用与指针的区别
- 在语法概念上引用就是一个别名,没有独立的空间,和其引用实体共用一块空间;而指针去开辟了四个字节的空间;
- 但从汇编代码看,在底层实现上,它们完全相同:
- 具体不同
- 引用在定义时必须初始化,指针没有要求
- 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何一个同类型实体
- 没有NULL引用,但有NULL指针
- 在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32位平台下占4个字节);
- 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小
- 有多级指针,但是没有多级引用;
- 访问实体方式不同,指针需要显式解引用,引用编译器自己处理;
- 引用比指针使用起来相对更安全