什么是引用
引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。(语法层面来讲)
但在底层实际上引用是开辟空间的,类似于指针
使用
- 引用做参数
(输出型参数)
(减少拷贝提高效率)(大对象/深拷贝类对象)
void swap(int& a, int& b)
{
int tmp = a;
a = b;
b = tmp;
}
void swap(int*& a, int*& b)
{
int* tmp = a;
a = b;
b = tmp;
}
int main()
{
int x = 11, y = 22;
cout << x << " " << y << endl;
swap(x, y);
cout << x <<" " << y << endl;
int* px = &x, * py = &y;
cout << px << " " << py << endl;
swap(px,py);
cout << px << " " << py << endl;
return 0;
}
- 引用做返回值
(减少拷贝提高效率)(大对象/深拷贝类对象)
修改返回值+获取返回值
引用返回被销毁的局部变量n,要小心
如果函数内部的变量出了函数作用域不消毁,那么就可以使用引用返回
回顾一下函数栈帧返回值是如何带回main函数的
把返回值拷贝到寄存器/临时空间带回调用函数中(寄存器放不下时,寄存器大小4byte 8byte)
为什么要开辟临时空间带回呢?
因为函数栈帧要被销毁,即使你销毁前把函数内部变量返回,返回的还是被销毁的变量
发现:静态区的变量带回也要开辟临时空间
总结:
1、基本任何场景都可以用引用传参。
2、谨慎用引用做返回值。出了函数作用域,对象不在了,就不能用引用返回,还在就可以用引用返回。
常引用----const修饰变量的引用
引用过程中,权限不能放大
int main()
{
const int a = 0;
int& b = a;
return 0;
}
但权限可以平移或者缩小
int main()
{
/*const int a = 0;
int& b = a;*/
int a = 0;
int& b = a;
const int& c = b;
++a;
printf("%d %d %d\n", a, b, c);
return 0;
}
算术转换发生时的临时变量
操作符两边不同类型 发生截断或者提升 会保存到临时变量,因为不能改变原数据
这里虽然int& rii = dd的类型不同
还有另外原因是发生算术转换的临时变量具有常性,相当于权限提升,所以不行
修改:
double dd = 1.11;
int ii = dd;
cout << ii << endl;
const int& rii = dd;
cout << rii << endl;
临时变量具有常性
临时变量x具有常性 ret1进行权限放大 是不可以的
修改:
int func1()
{
static int x = 0;
return x;
}
int main()
{
//int& ret1 = func1(); // 权限放大
const int& ret1 = func1(); // 权限平移
int ret1 = func1(); // 拷贝
return 0;
}