1.1 引用概念
引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。
类型& 引用变量名(对象名) = 引用实体;
注意:引用类型必须和引用实体是同种类型的
1.2 引用特性
1. 引用在定义时必须初始化
2. 一个变量可以有多个引用3. 引用一旦引用一个实体,再不能引用其他实体
引用本质上有地址,只是C++编译器隐藏了。
引用也是变量,是变量就有地址,有地址就占内存。
例如下面的代码:加粗的是c++代码,其他是汇编,可以看出两个引用都占用了一个指针大小的内存
int i = 1;
007B2712 mov dword ptr [i],1 在堆栈里开辟一个int大小内存存储1
int& ri1 = i;
007B2719 lea eax,[i] 取i的地址到eax寄存器
007B271C mov dword ptr [ri1],eax 把eax的值(就是刚才的i的地址)放到一个指针里
int& ri2 = i;
007B271F lea eax,[i]
007B2722 mov dword ptr [ri2],eax 把eax的值(就是刚才的i的地址)放到一个指针
里 int ii = ri1 + ri2;
所以引用是用指针来实现的,指针肯定要占用存储空间,也有地址,但是通过常规手段也无法找到引用的地址,取引用的地址,取来的是本尊的地址:
&ri1 &ri2 &i,都是一个值。
1.3 常量不能被引用
const int aa = 10;
//int &&bb = a; // build error
1.4使用场景--做形式参数时,可以改变实际参数的值。不存在从形参到实参的拷贝问题。可以提升效率
void changedfunc(int &a, int &b) {
int temp = a;
a = b;
b = temp;
}
void main() {
int x = 10, y = 20;
cout << "x = " << x << " y = " << y << endl;
changedfunc(x,y);
cout << "x = " << x << " y = " << y << endl;
//运行结果
// x = 10 y = 20
// x = 20 y = 10
}
1.5 使用场景--使用引用做返回值的时候要注意,不能返回局部变量的引用
int& func111() {
int a = 10;
int b = 20;
int tempresult = a + b;
int &result = tempresult;
return result;
}
void main() {
//有问题,func111函数的返回值个局部变量的引用,
//一般在func111调用完成后,该函数的局部变量会被系统回收,
//皮之不在,毛将安附?因此返回的引用也会有问题
int aaa = func111();
}
1.6 引用做形参,在方法内部可以改动形参的值影响实参,如果不想被影响,则使用const 修饰 引用即可
class T1 {
public:
int age;
char name[64];
};
//使用const 引用,可以防止user 修改T1的值(也就是修改实际参数)
void func222(const T1 &t) {
//t.age = 20;//build error,提示“表达式必须是可以修改的左值”
}