什么是引用
引用可以理解为变量的别名,外号,是隐含的指针操作
对某变量引用的操作就是对该变量的操作
引用必须初始化,一旦初始化就完成绑定,不得重新绑定或手动撤销绑定,其生命周期与其所在函数有关,与其绑定的变量无关
int a1=100;
void test(void){
int a2=90;
int &b1=a1;//b1是a1的别名
int &b2=a2;
cout<<"a1="<<b1<<endl;
b2--;//对引用操作
cout<<"a2="<<a2<<endl;//对b2的操作反映到a2上
}
int main(void){
test();
b1--;//报错not declared,虽然b1是对全局变量a1的引用,但因为b1初始化的函数已经退出,别名b1已被收回
}
引用有什么用
主要用于传递函数的参数和返回值,避免为函数构造临时变量,效率更高
当绑定对象为int,char等普通变量时可能体现不出,但当绑定对象是非常复杂的结构体时能明显观察到效率提高
struct A{
int val;
...
};
void test0(A a){
a.val=1;//普通传参在进入函数时会创建一个A类型临时变量将a的内容拷贝进来
}
void test1(A &a){
a.val=1;//引用传参不会创建临时变量,对a的操作会保留在a1中
}
void test2(const A &a){
a.val=2;//const引用时对a的操作是非法的
}
int main(void){
A a1;
a1.val=100;
test0(a1);//a1.val=100
test1(a1);//a1.val=1
test2(a1);//error
}
同样的,可以按引用进行函数值返回
int& test0(int& a){//一般用法
a++;
return a;
}
int& test1(int a){//warning
a++;
return a;
}
int& test2(void){
static int a=0;//函数内的static声明可以在函数外存在
return a;
}
int test4(int& a){
return a;
}
int main(void){
int a1;
a1=100;
test0(a1)=-100;//返回引用时,函数甚至可以作左值(a1=-100)
test1(a1);//warning,可编译通过,但用作左值会崩溃
test2();
test4(a1)=-200;//EROR,返回int的函数显然不能用作左值
}
引用和指针有何区别
引用是变量的一个别名,而指针本身就是一个变量,存储其指向对象的地址。这也导致对引用指向的对象和指针指向的对象进行操作时用法不同,引用是直接操作,指针要对*ptr操作
引用指向的对象不能改变,而指针可以
引用一定不为空,指针可能为空