文章目录
1.引用的概念和定义2.引用的特性3.引用的使用3.1 做函数返回值3.2 传参 3.3 其他使用 4.const的运用引用的权限问题;const修饰引用; 5.指针和引用的对比
1.引用的概念和定义
在介绍概念之前先说一下引用的符号——“ & ”;对于这个符号特别容易和取地址的符号——“ & ”混淆,要注意区分;
对于引用我们把它套入生活中可以更好的理解,比如我们给李明起个外号叫—“李四”,这里的 ”李四“ 在C++中就可以被叫做——引用,所以引用其实就相当于给变量起了一个别名,它的本质还是变量;
2.引用的特性
•
1.引⽤在定义时必须初始化
•
2.⼀个变量可以有多个引⽤
•
3.引⽤⼀旦引⽤⼀个实体,再不能引⽤其他实体
#include<iostream>using namespace std;int main(){int a = 0;// 引⽤:b和c是a的别名int& b = a;int& c = a;// 也可以给别名b取别名,d相当于还是a的别名int& d = b;++d;// 这⾥取地址我们看到是⼀样的cout << a << endl;cout << b << endl;cout << c << endl;cout << d << endl;cout << &a << endl;cout << &b << endl;cout << &c << endl;cout << &d << endl;return 0;}
在代码中,我们定义了一个变量“a”,对它取引用别名 “b” 之后,我们还可以在再对a取别名c,这两个都是a的引用,所以**引用(别名)的数量不受限制;**
然后我们也可以再对别名b取别名d,但是别名d还是a的别名;
而且当我们对别名d进行自增时,本质上相当于是对变量a的自增,
引用时取的别名是不会在内存中有新的地址的,它与变量a(引用主体)的地址相同(共用一个地址);
#include<iostream> using namespace std; int main() { int a = 10; // 编译报错:“ra”: 必须初始化引⽤//int& ra; int& b = a; int c = 20; b = c; // 这⾥并⾮让b引⽤c,因为C++引⽤不能改变指向, // 这⾥是⼀个赋值 cout << &a << endl; cout << &b << endl; cout << &c << endl; return 0;}
代码中当我们定义一个变量“ra”而没对他初始化时会报出下面的错误
所以**引用并不像指针一样,引用的主体必须初始化**;
对于引用时有多个主体的问题:
#include<iostream>using namespace std;int main(){ //int a = 10; //编译报错:“ra”: 必须初始化引⽤ /*int& ra; int& b = ra; int c = 20; b = c;*/ // 这⾥并⾮让b引⽤c,因为C++引⽤不能改变指向, // 这⾥是⼀个赋值 int a = 10; int c = 20; int& b = a; int& b = c; cout << &a << endl; cout << &b << endl; cout << &c << endl; return 0;}
>引用主体只能有一个;
3.引用的使用
3.1 做函数返回值
1.•
引⽤在实践中主要是于引⽤传参和引⽤做返回值中减少拷⻉提⾼效率和改变引⽤对象时同时改变被引⽤对象。
在c++中通过引用返回可以避免拷贝大型对象,提高性能。但需要注意避免返回局部变量的引用,因为这会导致悬挂引用(dangling reference,指向已被释放的内存地址。避免在删除对象后立即使用其引用)。
#include <iostream>#include <string>using namespace std;std::string& getString() { static std::string str = "Hello, World!"; return str;}int main() { std::string& refStr = getString(); std::cout << refStr << std::endl; // 输出 Hello, World! return 0;}
3.2 传参
2.•
引⽤传参跟指针传参功能是类似的,引⽤传参相对更⽅便⼀些。
在c++中传参分为值传参,引用传参;
1 .传值:函数接收参数的副本,在函数内部对参数的修改不会影响外部变量。
2.传引用:函数接收参数的引用,直接操作原始数据,避免了不必要的拷贝,提高了效率。
#include <iostream>void modifyValue(int& x) { x = 10;}int main() { int a = 5; modifyValue(a); std::cout << "a: " << a << std::endl; // 输出 a: 10 return 0;}
3.3 其他使用
引用不仅能对变量进行引用,还可以对数组,指针引用:
1.在引用数组时,必须要知道数组的大小;
#include<iostream>using namespace std;int main(){ int a = 10; int b = 10; int arr[5] = { 1,2,3,4,5 }; int& x = ar[0]; //ok int(&x)[5] = ar; //ok 没有[5]无法编译通过 return 0;}
2.引用指针时,跟引用变量一样,都是对引用主体取别名;
4.const的运用
引用的权限问题;
用const来修饰引用,主要的是涉及到一个权限的问题,在C++中权限只能缩小不能放大,而const在通常情况下可以帮我们解决这个问题;
//修改前//void Count(int& s)//{//}//修改后void Count(const int& s){}int main{//int a = 0;// 权限平移int& ra = a;// 指针和引用赋值中,权限可以缩小,但是不能放大const int b = 1;// rb引用b,b只有可读权限,rb可读可写,权限放大,不允许//int& rb = b;// 权限平移const int& rb = b;// rra引用a,权限缩小了,允许const int& rra = a;Count(a);//可以Count(b);//不可以,传参时候b的权限扩大了Count(rra);//不可以,同上}
使用const可以控制权限的大小;在我们修改函数Count之前,传 “b” 和 “rra” 都会因为权限放大而报错,这时我们就需要在函数参数中加入const来修饰参数体,加上const之后,a权限缩小,被允许,b和rra权限平移也可以
const修饰引用;
const T &p:表示p引用的对象的值不能通过p修改;
int main(){int n = 1;const int& p = n;p++;}
在代码中,p是n的引用,由于引用被const限制不能改变,但是我们可以通过改变主体来改变p;
#include<iostream>using namespace std;int mian(){int n = 1;const int& p = n;n++;cout << p;}
5.指针和引用的对比
在C++中,引用和指针都是用于间接访问其他变量的工具,但它们之间存在显著的差异。以下是对引用和指针的详细对比:
一、定义与概念
引用:
引用是某个已存在变量的别名。
引用在定义时必须初始化,且一旦初始化后,就不能再改变为其他变量的引用。
指针:
指针是存储变量地址的变量。
指针可以在任何时候指向不同的变量,也可以为空(即指向NULL或nullptr)。
二、内存管理
引用:
引用不需要显式分配或释放内存。
当引用所引用的对象离开作用域时,引用自动失效,无需手动处理。
指针:
指针需要显式分配和释放内存,通常使用new和delete(或在C语言中使用malloc和free)。
若忘记释放内存,可能会导致内存泄漏。
三、操作与灵活性
引用:
引用操作相对简单,不需要解引用操作符()。
引用不支持空引用,必须始终引用一个有效的对象。
引用不支持算术运算,因为引用不是一个对象,而是一个别名。
指针:
指针操作相对复杂,需要使用解引用操作符()来访问指针所指向的对象。
指针可以为空,且支持算术运算(如指针加减)。
指针支持操作符重载,可以重载指针相关的操作符以实现自定义行为。
四、使用场景与优缺点
引用:
优点:使用简单、安全,不容易出错。
缺点:不够灵活,一旦初始化后不能改变引用的对象。
使用场景:常用于函数参数传递(特别是需要修改参数值时)、返回值以及作为复合类型的成员(如类的成员变量)。
指针:
优点:灵活性强,可以指向不同的对象,支持动态内存分配和数据结构(如链表、树等)。
缺点:容易出错(如悬挂指针、野指针等),需要手动管理内存。
使用场景:动态内存分配、数据结构实现、函数参数传递(特别是传递数组或对象的地址时)。
五、其他差异
sizeof运算:
引用:sizeof引用得到的是被引用类型的大小。
指针:sizeof指针得到的是指针类型的大小(与平台相关,32位平台下为4字节,64位平台下为8字节)。
多级引用与多级指针:
引用:不支持多级引用(即不能有一个引用的引用)。
指针:支持多级指针(即可以有一个指向指针的指针)。
综上所述,C++中的引用和指针各有优缺点和使用场景。在选择使用哪种方式时,应根据具体需求和编程情境来决定。引用通常更容易使用且更安全,而指针则提供了更多的灵活性和控制。
但是在汇编语言的层面上“引用”就是“指针”,这一观点我们可以从反汇编中得到;