IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 引用(C++) -> 正文阅读

[C++知识库]引用(C++)

1.引用

引用并不是定义个新变量,而是给一个变量起一个新的名字,起别名的时候并没有开辟新的空间,而是和原来变量共同使用一块空间;

1.2 引用的定义

类型& 引用变量名(对象名) = 引用实体;

int main()
{
	int a = 0;
	int& b = a;    //b就是a的别名
}

其实可以这样理解(个人),因为&符号是取地址操作符嘛,int& 类型可以当做a不仅将值赋值给了b,地址也给了b,所以他们共用一块空间。

1.3 引用的特性

1:

因为b是a的别名,使用的是同一块空间,所以b的改变会导致a的改变

void test()
{
	int a = 0;
	int& b = a;
	cout << b << endl;
	b = 10;
	cout << b << endl; 
}

2:

引用的时候必须初始化

3:

引用一旦引用了一个实体就不能被改变

void test()
{
	int a = 0;
	int& ra = a;
	int& rra = a;  
	//ra和rra的实体只能是a,不能改变
}

1.4 引用的权限

1:权限对等和放大

const可以使一个变量的权限缩小(能赋值变成不能赋值),如果我取一个常量的别名会怎么样

void test()
{
	int& a = 20;
}

毫无疑问,编译器弹出了一个警告
在这里插入图片描述
因为一个常量怎么会有别名呢,如果我加上const呢

void test()
{
	const int& a = 20;
}

这时候编译器就没有报错,因为常量本来就不可以修改,那么我加上const后,a也就不能被修改,所以常量也是可以取别名的,但是权限不能放大;

2:权限缩小:

void test()
{
	int a = 20;
	const int& ra = a;
}

编译器没有报错,说明权限可以缩小

3: 类型转换

void test()
{
	int a = 20;
	
	char& ra = a;//报错
	int& rra = a;//不报错
	double& rra = a;//报错
}

但是,如果我加上const

void test()
{
	int a = 20;
	
	const char& ra = a;
	const int& rra = a;
	const double& rra = a;
}

以上编译器都不会报错

这是因为在引用相同类型的时候,是直接将a进行引用,而在进行不同类型的引用时,会产生类型转换,那么会参生一个临时变量原来储存a转换后的值,再将临时变量赋值给ra,在这时如果取直接引用,那么相当于引用了临时变量,而临时变量具有常性(不可修改),所以会报错,那么加上const后就不会报错。

4:总结

以上结果可以说明,引用的权限可以缩小,但是不能放大,并且引用只能引用同之种类型;

1.5 引用做参数和返回值

1:参数

void test(int& a)
{
	a = 20;
}

int main()
{
	int a = 0;
	test(a);
}

形参a就是实参a的别名,改变了形参a就改变了实参a的值,跟传地址的形式是一样的,但是比传地址好用。

但是如果传常量或者是其他类型的数据就会报错

void test(int& a);

void test2(const int& a);

int main()
{
	char a;
	double b;
	test(20);
	test(a);
	test(b);

	test2(20);
	test2(a);
	test2(b);
}

加上了const就不会报错,道理和上面一样

2:返回值

想想,引用可以作为函数返回值的别名吗

形式一:

int test()
{
	int a = 10;
	return a;
}

int main()
{
	int& a = test();    //报错
	const int& a = test();  //不报错
	return 0;
}

因为返回a的值时,会使用一个寄存器或者是一个临时变量来存储返回值,待test函数被销毁的时候,a的值就会通过寄存器或者是临时变量来做返回值,所以如果直接引用,那么相对于引用了临时变量或者是寄存器,但是它们都是不可改的,所以要加上const才能做引用;

形式二:

int& test()
{
	int b = 10;
	return b;
}

int main()
{
	int& a = test();
	return 0;
}

这其实才是返回值做引用的正确方式,a就是test函数中b的别名,但是还有一些错误,当test函数调用完后空间会被回收,但是a中的地址仍然是test函数中b的地址,但是b的地址已经被系统回收,强行访问会有错误;

形式三:

int& test()
{
	static int b = 10;
	return b;
}

int main()
{
	int& a = test();
	return 0;
}

b的值是全局静态变量,所以b的空间不会随着栈帧销毁被回收,这才是正确的使用方式。

因为b是全局的,那么我第一次得到b的别名后,也可以不用接收返回值
例:

int& add(int a,int b)
{
	static int ret;
	ret = a + b;
	return ret;
}

int main()
{
	int& a = add(10,20);
	cout << a << endl;
	add(30, 40);
	cout << a << endl;
	return 0;
}

结果:

在这里插入图片描述

1.6 引用和指针的区别

不同点:

1:引用在定义时没有开辟新的空间,而指针在定义是开辟了空间原来储存地 址
2:引用在定义的时候必须要初始化,而指针不需要
3:有多级指针,但是没有多级引用
4:指针定义后可以被修改,而引用定义后不能被修改
5:访问实体方式不同,指针需要使用解引用操作符访问储存的地址的空间,引用编译器自己处理
6:引用比指针使用起来相对更安全

相同点:
本质是引用和指针是同一个东西,因为引用实现的底层逻辑和指针实现的底层逻辑是一样的,也就是说,其实引用是消耗空间的。

在这里插入图片描述

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-05-15 11:29:21  更:2022-05-15 11:30:00 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/10 10:31:36-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码