目录
C++中的引用是一种特殊的类型,它是一个别名(或者叫作“引用名”),用来指向另一个变量。一旦引用被初始化为一个变量,它就不能被改变指向另一个变量。引用必须在声明时被初始化,并且之后引用名和它所指向的变量名可以互换使用。引用是C++中一个非常强大的特性,它提供了一种高效的方式来操作变量,同时保持代码的简洁性和可读性。以下是C++引用的一些关键点:
/*
1.引用的声明与初始化
2.别名
3.引用与指针的区别
4.常量引用|const与引用
5.引用作为函数参数
6.引用返回值
7.右值引用(C++11新特性)
8.引用的实现
*/
int num1 = 1;
int &n = num1; //引用被声明时必须进行初始化,n为num1的引用,不可改变引用关系
n = 100 ;
cout << num1; //100,对引用进行操作就是其指向的变量进行的操作
1.引用的声明与初始化
引用在声明时必须被初始化,并且一旦初始化后,其指向的变量不能改变。引用实体和引用类型必须是相同的数据类型
2.别名
引用是它所指向变量的别名。因此,对引用的操作实际上就是对它所指向的变量的操作。
3.引用与指针的区别
4.常量引用 | const与引用
//常量引用
int num1 = 100;
const int& num = num1;
// num = 1;报错,const修饰的引用类型不可以修改,可以指向静态变量/非静态变量
num1 = 1000;
cout << num1 << endl; //1000
5.引用作为函数参数
引用作为函数参数时,可以在函数内部对参数进行修改,提高函数的运行效率(值的传递机制是通过将“形参=实参”进行的,会形成一个实参的副本,参数为引用时,已有了实参的信息,进而可以避免复制开销,提高函数运行效率)
//引用作为函数参数
void swap(int &a,int &b) {
int temp = a;
a = b;
b = temp;
}
int main()
{
int a = 0, b = 0;
cout << "请依次输入a和b的值:";
cin >> a >> b;
swap(a, b); //在swap函数中修改了a和b
cout << "a=" << a << endl << "b=" << b << endl;
return 0;
}
6.引用返回值
引用作为返回值时,不会在内存中产生返回值内存的副本(否则在栈区产生返回值的副本,占用内存,函数调用结束后释放)
//引用作为返回值
int& swap(int a) {
a += 2;
return a;
}
int main()
{
int b = 0;
cin >> b;
int c = swap(b);
cout << "c=" << c << endl;
return 0;
}
7.右值引用(C++11新特性)
右值引用(&&)用于优化移动操作以避免不必要的深拷贝。右值引用只能绑定到即将被销毁的对象上。具体来说,当函数返回一个临时对象时,可通过右值引用直接移动该对象,避免复制,提高程序的运行效率。
右值引用与move、RVO(Return Value Optimization)和universal reference等概念紧密相关
8.引用的实现
C++中的引用(&)是变量的一个别名,它提供了一种方式来间接访问该变量。从实现的角度来看,引用通常被编译器实现为指针,但对程序员来说,它们表现得像另一个变量名。
- 编译器实现层面
- 从编译器的角度来看,引用在内部通常是通过指针来实现的。当创建一个引用时,编译器会在幕后将引用转换为一个指针常量。例如,对于
int a = 10; int& ref=a;
,编译器可能会将其处理为类似于int* const ref_ptr = &a
的形式。这里ref_ptr
是一个指向a
的常量指针,它不能被重新指向其他变量,这就保证了引用一旦初始化就不能再引用其他对象的特性。
- 从编译器的角度来看,引用在内部通常是通过指针来实现的。当创建一个引用时,编译器会在幕后将引用转换为一个指针常量。例如,对于
- 内存布局层面
- 引用变量和被引用变量的内存地址是相同的。因为它们本质上是同一块内存的不同表示方式。以
int
类型为例,如果变量a
的地址是0x1000
,那么引用ref
的地址也是0x1000
。当通过引用访问变量时,实际上是通过这个共享的内存地址来读写数据。
- 引用变量和被引用变量的内存地址是相同的。因为它们本质上是同一块内存的不同表示方式。以