🍪一、引用的概念
引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。
比如:李逵,在家称为"铁牛",江湖上人称"黑旋风"
比如:抓 “周树人” 和我 "鲁迅"有什么关系🤭,本质上其实是一个人
🚩引用的操作符: &
🚩类型& 引用变量名(对象名) = 引用实体
🌰举个栗子演示👇
int main() { int a = 0; int& b = a; //引用 cout << &a << endl; cout << &b << endl; return 0; }
☝️代码段中相当于给变量a取了一个别名b,通过标识名b可以在其被定义的作用域中访问变量a,可以看到地址是一样的,说明a和b共用同一块内存空间
🚨注意:引用类型必须和引用实体是同种类型的
🍪二、引用的特性
🍿1、引用在定义时必须初始化
🥰请看代码与注释👇
void TestRef() { int a = 10; // int& ra; // 该条语句编译时会出错 int& ra = a; cout << a << " " << &a << endl; cout << ra << " " << &ra << endl; } int main() { TestRef(); return 0; }
🚨int& ra; 该条语句编译时会出错,是不可以的,必须要进行初始化
🍿2、一个变量可以有多个引用
🚩一个变量可以有多个引用,并且引用可以嵌套定义
🥰请看代码与注释👇
void TestRef() { int a = 10; // int& ra; // 该条语句编译时会出错 int& ra = a; // ra是a的引用 int& rra = a; // rra是a的引用 int& rrra = ra; // rrra是ra的引用 cout << a << " " << &a << endl; cout << ra << " " << &ra << endl; cout << rra << " " << &rra << endl; cout << rrra << " " << &rrra << endl; } int main() { TestRef(); return 0; }
基于引用这种可以嵌套定义并且无需多次解引用就可以直接访问被引用变量的这种特性,很多时候使用引用可以避免多级指针的出现
🍿3、引用一旦引用一个实体,再不能引用其他实体
🌰举个栗子演示👇
void TestRef() { int a = 10; int b = 20; int& x = a; int& x = b; cout << a << " " << &a << endl; cout << x << " " << &x << endl; cout << b << " " << &b << endl; cout << x << " " << &x << endl; }
由于这个特性,引用无法完全代替指针(比如链表中结构体的next指针无法用引用来代替,因为引用一旦引用一个实体,再不能引用其他实体),灵活性也不如指针,但是引用也因此比指针更安全,这也是引用这个语法的设计初衷之一(使用指针很容易出现野指针,非法访问内存空间的情况)
🍪三、常引用(被const 修饰的引用)
🚨在引用的过程中,权限可以平移,权限可以缩小,但是权限不能放大!
🍿1、权限的放大
假如a是鲁智深 可以喝酒 可以吃肉 不能杀人
给a取个别名b 叫花和尚 可以喝酒 可以吃肉 可以杀人?
a(鲁智深)和 b(花和尚)是同一个人,当然不可以杀人
🌰举个栗子👇
int main() { //权限的放大 const int a = 0; int& b = a; return 0; }
🍿2、权限的平移
🌰举个栗子👇
int main() { //权限的平移 const int a = 0; const int& b = a; return 0; }
🍿3、权限的缩小
🌰举个栗子👇
int main() { //权限的缩小 int a = 0; //a可以修改,可以影响b const int& b = a; return 0; }
a可以修改,可以影响b
🍿4、临时变量具有常性
🌰举个栗子👇
int main() { int i = 0; double& d = i;//临时变量具有常性 return 0; }
✅正确操作👇
int main() { int i = 0; const double& d = i; return 0; }
🚩这里涉及一个知识点:
代码段中b去引用i,i会发生隐式类型转换,i转换的结果会存入一个临时空间中。
(当赋值等号右边有运算表达式或有变量发生类型转换时,表达式或类型转换的结果都会先存入一个临时空间后再赋值给等号左边的变量)因此这里的d引用的实质上是一块临时空间: