一、引用
引用不是定义一个新的变量,而是给一个已有的变量起一个别名。
类型 &引用变量名 = 已定义过的变量名;
注:1)一个变量可以有多个别名;
2)引用必须初始化;
3)引用只能在初始化时引用一次,不能在成为其他变量的别名。
#include <iostream>
using namespace std;
int main()
{
int a = 13;
//b,c,d都是a的别名,代表了同一个变量
//一个变量可以有多个别名
int& b = a;
int& c = a;
int& d = a;
cout << "a=" << a << endl;
cout << "b=" << b << endl;
cout << "c=" << c << endl;
cout << "d=" << d << endl;
//引用只能被初始化一次,不能再次被初始化成为其它变量的别名
int e = 20;
b = e; //这是一个赋值操作,把e的值赋给了b;并没有对b进行再次初始化,使b成为其它变量的别名
//由于a,b,c,d指的是同一变量的别名,打印出来都是20
cout << "a=" << a << endl;
cout << "b=" << b << endl;
cout << "c=" << c << endl;
cout << "d=" << d << endl;
system("pause");
return 0;
}
const引用:
#include <iostream>
using namespace std;
int main()
{ //常量具有常性,只有常引用才能引用常量
const int a = 10;
const int& b = a;
//给一个常量建立引用时,也要加上const
int c = 30;
const int &d = c;
system("pause");
return 0;
}
上面建立的都是相同类型间的引用,那么不同类型之间可以使用引用吗?
二、引用的应用
1、引用做参数
相比于C语言中的传地址要方便的多,且效率更好。
void swap1(int *x, int *y)
{
int tmp = *x;
*x = *y;
*y = tmp;
}
void swap2(int& x, int& y)
{
int tmp = x;
x = y;
y = tmp;
}
int main()
{
int a = 10;
int b = 20;
int beg1 = GetTickCount();
for (int i = 0; i < 100000000; i++)
{
swap1(&a, &b); //传址
}
int end1 = GetTickCount();
cout << "传指针:" << end1 - beg1 << endl;
int beg2 = GetTickCount();
for (int i = 0; i < 100000000; i++)
{
swap2(a, b); //传引用
}
int end2 = GetTickCount();
cout << "传引用:" << end2 - beg2 << endl;
system("pause");
return 0;
}
注:当我们不想在调用的函数内部改变该变量时,可以使用const引用。
2、引用做返回值
传值返回:用引用接收
int Add(int a, int b)
{
//返回的是一个临时变量(匿名变量),该变量具有常性,用引用接收时要加上const,相当于给这个匿名变量起了一个别名
return a + b;
}
int main()
{
const int& ret = Add(10, 20);
cout << "10+20=" << ret << endl;
system("pause");
return 0;
}
传引用返回:
int& Add(int a, int b)
{
int c = a + b;
return c;
}
int main()
{
int& ret = Add(10, 20);
cout << "10+20=" << ret << endl;
system("pause");
return 0;
}
可以这样理解:
三、深入理解引用
先用汇编代码查看上面做引用返回的函数代用过程:(截取部分)
我们发现,在函数调用过程中,是把c的地址放到寄存器eax中,函数调用结束后,回到main函数的栈桢中,再从eax中的地址找到该地址的值。这时候,这个地址已经不再被变量c所使用,也就是说,从该地址取到的值不一定是我们想要的值。
所以,结论是:
1)不要返回一个临时变量的引用;
2)若出了作用域,该变量还存在,尽量返回该变量的引用。
对比返回指针的方式与返回引用的方式:
从汇编层讲,它们的实现是一样的;但从语法上讲,引用不用开辟新的空间,指针需要。
四、引用与指针的区别
1、引用只能在初始化时引用一次,之后就不能在改变为其它变量的引用(从一而终);而指针可以改变很多次。
2、引用必须指向有效的变量,指针可以为空。
3、sizeof(引用),结果为变量的大小;而sizeof(指针),结果为地址的大小。
4、自增自减含义不同。引用是该变量自增自减1;而指针是指针加或减类型的大小。
5、引用比指针更安全;指针比引用更灵活。