目录
一、应用的概念和定义
引用不是新定义⼀个变量,而是给已存在变量取了⼀个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同⼀块内存空间。
类型&引用别名=引用对象;
#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 << ' ' << &a << endl;
cout << b << ' ' << &b << endl;
cout << c << ' ' << &c << endl;
cout << d << ' ' << &d << endl;
return 0;
}
(以上面代码为例)我们创建了一个变量a,给a取了别名b和c,再给b取了一个别名d,然后d++。
其实打印结果是一样的。说明它们(b、c、d)是同一个数的别名。
二、引用的特性
- 引用在定义时必须初始化。
- ⼀个变量可以有多个引用。
- 引用⼀旦引用⼀个实体,再不能引⽤其他实体。
#include<iostream>
using namespace std;
int main()
{
int a = 10;
// 编译报错:“ra”: 必须初始化引⽤
//int& ra;
int& b = a;
int c = 20;
// 这⾥并⾮让b引⽤c,因为C++引⽤不能改变指向,
// 这⾥是⼀个赋值
b = c;
cout << &a << endl;
cout << &b << endl;
cout << &c << endl;
return 0;
}
三、引用的使用
引用在实践中主要是于传值传参和引用传参做返回值中减少拷贝提搞效率和改变引用对象时同时改变被引用对象。
引⽤传参跟指针传参功能是类似的,引⽤传参相对更⽅便⼀些。
我们在学C语言的时候,当我们要写一个交换函数Swap()的时候,我们先传要交换数据的变量的地址,然后在写交换的代码。在C++中我们可以使用别名来写一个交换函数。
#include <iostream>
using namespace std;
void Swap(int& rx, int& ry)
{
int tmp = rx;
rx = ry;
ry = tmp;
}
int main()
{
int x = 0, y = 1;
cout << x << " " << y << endl;
Swap(x, y);
cout << x << " " << y << endl;
return 0;
}
在Swap()函数中,rx是x的别名,ry是y的别名,当我们改变rx和ry的时候就是在改变x和y。
四、const引用
- 可以引用⼀个const对象,但是必须用const引用。const引用也可以引用普通对象,因为对象的访
- 问权限在引用过程中可以缩小,但是不能放大。
- 不需要注意的是类似 int& rb = a*3; double d = 12.34; int& rd = d; 这样⼀些场景下a*3的和结果保存在⼀个临时对象中, int& rd = d 也是类似,在类型转换中会产⽣临时对象存储中间值,也就是时,rb和rd引用的都是临时对象,而C++规定临时对象具有常性,所以这里就触发了权限放大,必须要用常引用才可以。
- 所谓临时对象就是编译器需要⼀个空间暂存表达式的求值结果时临时创建的⼀个未命名的对象,C++中把这个未命名对象叫做临时对象。
int main()
{
const int a = 10;
// 编译报错:error C2440: “初始化”: ⽆法从“const int”转换为“int &”
// 这⾥的引⽤是对a访问权限的放⼤
int& ra = a; //错误
// 这样才可以
const int& ra = a;
// 编译报错:error C3892: “ra”: 不能给常量赋值
ra++;//错误
// 这⾥的引⽤是对b访问权限的缩⼩
int b = 20;
const int& rb = b;
// 编译报错:error C3892: “rb”: 不能给常量赋值
rb++;//错误
return 0;
}
在C++中访问权限只能缩小不能放大,如上面一个const int 类型引用了一个int类型 b,这里发生了权限的缩小。
五、指针和引用的关系
C++中指针和引用在实践中它们相辅相成,功能有重叠性,但是各有自己的特点,互相不可替代。
• 语法概念上引用是⼀个变量的取别名不开空间,指针是存储⼀个变量地址,要开空间。
• 引用在定义时必须初始化,指针建议初始化,但是语法上不是必须的。
• 引用在初始化时引⽤⼀个对象后,就不能再引用其他对象;⽽指针可以在不断地改变指向对象。
• 引用可以直接访问指向对象,指针需要解引用才是访问指向对象。
• sizeof中含义不同,引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32位平台下占4个字节,64位下是8byte)
• 指针很容易出现空指针和野指针的问题,引⽤很少出现,引用使用起来相对更安全⼀些。