什么是变量的引用
对一个数据可以建立一个引用,它的作用是为变量起一个别名,这是c++对c的一个主要扩充。
注意
- 引用不是一种独立的数据类型,对引用只有声明,没有定义。
- 声明一个引用时,必须同时使之初始化。特殊情况,可以不用初始化,如引用作为函数形参时,可以不用初始化,而在函数调用时虚实结合实现的。
- 在声明一个引用后,不能使之作为另外一个变量的引用。
- 不能建立引用数组
- 不能建立引用的引用
- 可以取引用的地址
- 区别引用声明符&和地址运算符&
引用作为函数参数
c++之所以增加引用机制,主要是把它作为函数形参,以扩充函数传递数据的功能。
分析下列三段交换代码
void swap(int a,int b)//传值
{
int temp=a;a=b;b=temp;
}
void swap(int *a,int *b)//传值
{
int temp=*a;*a=*b;*b=temp;
}
void swap(int &a,int &b)//传地址
{
int temp=a;a=b;b=temp;
}
分析上述三种交换代码,可以发现,前两种方式传递的时实参的值。注意第二个传递的也是变量的值,无非这个值是变量的地址,这个是初学者容易搞错的地方。在方式3中,函数的实参是变量名称,而传递的是变量的地址,这个才是传址方式。
总结起来就是:
函数的实参是变量名称,传递的是变量的地址,这个才是传址方式。其他为传值方式。
最后要注意的是,引用不仅可以引用普通的变量,而且还可以引用类对象。
引用作为函数返回值
注意:1.不要返回局部变量的引用,因为局部变量在函数调用完成后,就被系统自动释放了。
#include <iostream>
using namespace std;
int& fun()
{
int a = 10;
return a;
}
int main()
{
int &p = fun();
cout << p << endl;//默认保留一次
cout << p << endl;//已经释放
return 0;
}
2.函数作为左值
#include <iostream>
using namespace std;
int& fun()
{
static int a = 10;//静态变量,保存在全局区
return a;
}
int main()
{
int &p = fun();
cout << p << endl;
cout << p << endl;
fun() = 100;//函数作为左值
cout << p << endl;
cout << p << endl;
return 0;
}
引用的本质
在c++内部,引用的本质是一个指针常量(* const)
int &p=a;//自动转换为int * const p=&a;
常量引用
常量引用主要用于形参,防止在函数内部改变对象的值。
可以参考effective c++条款20:尽量以pass-by-reference-const替换pass-by-value。