C++的引用概念及用法
1.引用的概念及用法
引用:给一个已经定义的变量重新起一个别名。
表示方式和指针相似,不同的是用&代替了*,对引用的操作与对变量直接操作完全一样。
表示方式:类型 &引用变量名 = 已定义过的变量名;
引用的特点:
1. 一个变量可取多个别名
2. 引用必须初始化
3. 引用只能在初始化的时候引用一次,不能改变为再引用其他的变量。因为引用变量若改为其他变量,就相当于将之前被引用的变量的值改为此处的值。
2.引用做参数
①大家都知道普通的函数传参的话,形参是临时变量。形参是实参的一份临时拷贝,对拷贝的内容进行修改,并不会改变原先的内容。
void Swap(int p, int q)
{
int tmp;
tmp = p;
p = q;
q = tmp;
}
int main()
{
int a = 10, b = 20;
printf("a = %d ,b = %d\n", a, b);//10 ,20
Swap(a, b);
printf("a = %d ,b = %d\n", a, b);//10, 20
return 0;
}
②引用传参,形参是引用类型,则形参是实参的别名。虽是别名,但是指的是一个东西,形参和实参是一块地址。因此,形参变实参也会变。如若传参不希望改变实参的值,可以给形参添加const限定修饰符。
void Swap(int& p, int& q)
{
int tmp;
tmp = p;
p = q;
q = tmp;
}
int main()
{
int a = 10, b = 20;
printf("a = %d ,b = %d\n", a, b);//10 ,20
Swap(a, b);
printf("a = %d ,b = %d\n", a, b);//20,10
return 0;
}
③指针传参的话,形参改变,实参的值也会被改变。实参传递的是自己的地址,形参指向实参的地址,对形参解引用就是实参的值,进而对实参进行修改。
void Swap(int *p, int *q)
{
int tmp;
tmp = *p;
*p = *q;
*q = tmp;
}
int main()
{
int a = 10, b = 20;
printf("a = %d ,b = %d\n", a, b);//10 ,20
Swap(&a, &b);
printf("a = %d ,b = %d\n", a, b);//20,10
return 0;
}
④指针传参和引用传参的效率比较
void PointSwap(int *p, int *q)
{
int tmp;
tmp = *p;
*p = *q;
*q = tmp;
}
void QuoteSwap(int& p, int& q)
{
int tmp;
tmp = p;
p = q;
q = tmp;
}
int main()
{
int a = 10, b = 20;
int point_func_begin,point_func_end;
int quote_func_begin,quote_func_end;
cout << "a = " << a << " ,b = " << b << endl;
point_func_begin = GetTickCount();
for (int i = 0; i < 1000000; i++)
{
PointSwap(&a, &b);
}
point_func_end = GetTickCount();
quote_func_begin = GetTickCount();
for (int i = 0; i < 1000000; i++)
{
QuoteSwap(a, b);
}
quote_func_end = GetTickCount();
cout << "a = " << a << ", b = " << b << endl;
//各机器所用时间数据可能有所不同,但相同的是在调用引用函数明显比指针函数更省时间
cout << "point func time = " << point_func_end - point_func_begin << endl;//16ms
cout << "quote func time = " << quote_func_end - quote_func_begin << endl;//31ms
return 0;
}
3.引用做返回值
int& Add(int a, int b)
{
int result = a + b;
return result;
}
int main()
{
int ret;
ret = Add(10, 20);
printf("%d\n", ret);
return 0;
}
4.汇编层看引用的特性
第一个图没有采用引用做返回值,第二个图用引用做返回值
关于最后dword ptr指令:
dword 双字 就是四个字节
ptr pointer缩写 即指针
[ ]里的数据是一个地址值,这个地址指向一个双字型数据
第一个图mov eax,dword ptr [result]
就是把result地址指向的双字内容赋给eax
第二个图 lea eax ,[result]
lea取有效地址指令 (Load Effective Address ),把result的地址给eax
5.引用和指针的区别
引用只能在定义时初始化一次,之后不能改变指向其它变量(从一而终);指针变量的值可变。
引用必须指向有效的变量,指针可以为空。
sizeof指针对象和引用对象的意义不一样。sizeof引用得到的是所指向的变量的大小,而sizeof指针是对象地址的大小。
指针和引用自增(++)自减(–)意义不一样。
相对而言,引用比指针更安全。