【基础知识】引用是什么?
1 为什么会出现引用?
在生活中,我们可能会给一些同学起外号,以“吴磊”同学为例,我们可以叫他“吴三石”,当我们叫到这个外号的时候就自然而然地想到“吴磊”同学,“吴三石”就是他的别名,而引用也可以这样简单理解:在语法层面上,引用就是取别名。
引用的出现是为了解决一些问题,主要包括:
● 避免拷贝构造函数创建临时对象所带来的开销。当将一个对象作为函数参数传递或返回时,如果使用传值方式,则会调用拷贝构造函数创建一个临时对象,这会带来额外的开销,而使用引用则可以避免这种开销。
● 让我们在函数内部修改传入的对象。如果不使用引用,则只能通过指针来实现这一点。
2 引用是什么?
在 C++ 中,引用是一种复合类型,它是一个对象的别名。引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共有一块内存空间。
语法格式: 类型 & 引用变量名(对象名) = 引用实体
例子:
int main(){//引用:取别名int a = 10;int& b = a;//定义引用类型int& c = b;return 0;
}
本段代码中,a 变量取了 b,c,可以通过调式观察它们的内存。
![](/assets/blank.gif)
通过调取内存可以发现,a、b、c 所指向的是同一块内存空间。
注意:
引用类型必须和引用实体是同种类型的
3 引用的特性
引用的三个特性:
1、引用变量创建必须初始化
由于引用是对已经存在的变量进行取别名,因此使用引用时,必须指定变量(初始化)
eg: int &d; //错误,为初始化
2、引用变量不能赋值为空,必须指向一个房子
3、引用变量不可以改变指向,不能修改引用关系
因为引用一旦引用了一个已经存在的实体,就是这个实体的别名,当然不能再成为其他实体的别名。
4 常引用
声明方式:
const 类型标识符 &引用名 = 目标变量名
用这种方式声明的引用,不能通过引用对目标变量的值进行修改,从而使引用的目标成为 const ,达到了引用的安全性.
int main(){//1.const int x = 20;int& y = x;return 0;
}
当我们编译这段代码发现编译器报出错误警告:无法从“const int”转换为 “int &”
![](/assets/blank.gif)
这是因为我们在引用的时候要遵守引用的规则:
引用规则: 对原变量的引用,权限不能放大
这段代码中 x 变量是 const 修饰的一个常变量,只有可读权限。而我们引用的类型是 int,不仅有可读权限,还有可修改权限。这就造成了对原变量的权限放大。根据我们引用原则知道,对原变量的引用,权限是不能放大的,这就是为什么这段代码会报错的原因。
那我们再来看这一段代码,他能否编译成功?
int main()
{//2.const int x = 20;const int& y = x;//不变//3.int c = 30;const int& d = c;//缩小return 0;
}
![](/assets/blank.gif)
这段代码我们发现编译成功了,我们也可以轻松地分析出这里的引用是遵守引用规则的,我们发现,权限不变或者权限缩小都是符合规则的,唯一需要注意的是:权限不能放大。
5 引用的使用场景
1、函数参数传递:
在函数定义中,可以使用引用作为参数来传递变量的值,避免复制大型对象或数组,提高程序的执行效率。
引用可以作为函数的参数进行传递,这样可以避免复制参数值而浪费空间和时间。同时,函数内对引用参数的修改也可以影响到函数外的实际参数。
void swap(int& a, int& b) {int temp = a;a = b;b = temp;
}int main() {int x = 5, y = 10;swap(x, y);cout << "x = " << x << ", y = " << y << endl;return 0;
}
2、函数返回值
在函数中,可以使用引用作为返回值类型,避免返回大型对象或数组的副本,提高程序的执行效率。
引用可以作为函数的返回值,这样可以避免返回大量数据而浪费空间和时间。同时,函数返回的引用也可以用于左值赋值操作,从而改变原始数据的值。
int& max(int& a, int& b) {return (a > b) ? a : b;
}int main() {int x = 5, y = 10;max(x, y) = 20;cout << "x = " << x << ", y = " << y << endl;return 0;
}
![](/assets/blank.gif)
3、遍历数组
在遍历数组时,可以使用引用来避免对数组元素的复制。
int arr[5] = {1, 2, 3, 4, 5};
for (int& x : arr) {x *= 2;
}
4、类成员变量
在类中,可以使用引用类型的成员变量来避免复制对象的副本,节省内存,提高程序的执行效率。
class Vector {
public:Vector(int size) : size(size), data(new int[size]) {}int& operator[](int index) {return data[index];}
private:int size;int* data;
};int main() {Vector v(5);for (int i = 0; i < 5; i++) {v[i] = i + 1;}for (int i = 0; i < 5; i++) {cout << v[i] << " ";}cout << endl;return 0;
}
5、操作符重载
在 C++ 中,可以使用引用来实现操作符重载。例如,可以重载“=”操作符,使用引用来实现对象之间的赋值操作。
class MyString {
public:MyString& operator=(const MyString& other) {if (this != &other) {delete[] data;size = other.size;data = new char[size];memcpy(data, other.data, size);}return *this;}
private:int size;char* data;
};
6 引用真的不占内存空间吗?
在 C++ 中,引用本身不会占用额外的内存空间,因为引用本质上只是一个别名或者说是指针的另一种表现形式。换句话说,当我们声明一个引用变量时,它只是为原变量起了一个别名,引用变量和原变量指向同一个内存地址,因此引用变量不需要分配额外的内存空间。
例如,以下代码中的 ”&ref“ 就是一个引用变量,它不会分配任何内存空间:
int x = 10;
int& ref = x;
然而,需要注意的是,对于一些内置类型以外的复合类型,如类或结构体,其引用的行为可能于内置类型有所不同。例如,如果我们在类中声明一个引用成员变量,那么这个引用变量实际上会占用一定的内存空间,因为引用本身需要在类中分配 空间。不过这种情况并不常见。
引用的底层实现通常是通过指针来实现的,而指针是需要占用内存空间的,因此,当我们使用引用时,实际上是在使用底层指针所指向的对象,而不是引用本身。在这种情况下,所占用的内存空间取决于所引用的对象的类型和 大小,而不是引用本身。
【基础知识】引用是什么?相关推荐
- [003]Reference in C++---C++引用基础知识篇
最近在搞C++的引用,闲来无事,顺便写写引用的基础知识 引言:什么是引用 引用就是某一变量(目标)的一个别名,对引用的操作与对变量直接操作完全一样. 引用的格式: 数据类型 &引用变量名 = ...
- swift 引用swift_Swift Swift中的单元测试:基础知识
swift 引用swift In this first part of the Unit Testing in Swift series, we will cover how to add a uni ...
- java的一些基础知识(引用BlogJava 落花飞雪)
java的一些基础知识(引用BlogJava 落花飞雪) <Practical Java>笔记 1. 声明是什么? String s = "Hello world!" ...
- python常用变量名_python基础知识整理
Python Python开发 Python语言 python基础知识整理 序言:本文简单介绍python基础知识的一些重要知识点,用于总结复习,每个知识点的具体用法会在后面的博客中一一补充程序: 一 ...
- PHP内核介绍及扩展开发指南—基础知识
一. 基础知识 本章简要介绍一些Zend引擎的内部机制,这些知识和Extensions密切相关,同时也可以帮助我们写出更加高效的PHP代码. 1.1 PHP变量的存储 1.1.1 zval结构 Zen ...
- ue4 函数和宏区别_【UE4】通俗易懂 用蓝图来学习 C++ 基础知识
[前言]: 用老罗来学UE蓝图: https://zhuanlan.zhihu.com/p/135297007zhuanlan.zhihu.com 再开个脑洞,用蓝图来类比学习C++基础知识. C+ ...
- SQL 数据完整性 基础知识
数据完整性 基础知识 实体完整性<?XML:NAMESPACE PREFIX = O /> 实体完整性将行定义为特定表的唯一实体.实体完整性通过索引.UNIQUE 约束.PRIMARY K ...
- java基础知识点_「Java面试题/知识点精华集」20000+字的Java基础知识篇(2020最新版) !
" 本文已经收录进我的 79K Star 的 Java 开源项目 JavaGuide:https://github.com/Snailclimb/JavaGuide (「Java学习+面试指 ...
- 计算机基础知识_2020年河北省高职单招计算机基础知识和实践技能培训
本考纲是根据教育部2014年4月中华人民共和国教育部<中等职业学校专业教学标准(试行)>(教职成厅函[2014]11号)颁布的<中等职业学校计算机应用专业教学标准>.<中 ...
- 《Python基础知识全家桶》
目录 1.实现一行输入多个数字,用空格隔开 2.实现一行输入多个单词,用","隔开 3.列表 4.for循环 5.切片 6.二维列表 7.元组 8.字典 set容器 9.嵌套 字典 ...
最新文章
- Java 线程池中的线程复用是如何实现的?
- es获取最大时间的记录_大屏幕大智慧,腕上私教+生理周期,荣耀手表ES评测
- 2.6 Go 读取CSV
- java 数据库连接池 开源_开源自己开发的一个JAVA数据库连接池,效果还算可以。...
- appium java 点击事件_java – 无法使用Appium在Android中的权限对话框中单击“允许”按钮...
- 不会诈骗的公司 都倒闭了
- 复制release文件到另一台电脑.exe文件无法运行_电脑技巧:电脑版微信双开(或微信多开)?用start指令可以解决...
- Anaconda jupyter-notebook 添加kernel
- traceroute tracert
- HR人力资源系统软件价格?哪家HR人力管理系统好
- 数学史思维导图_高中数学课堂教学中思维导图的制作运用
- postman(一)常用的Tests方法
- FPGA 频率计实验
- ubuntu16.04下安装录屏软件OBS studio
- AndroidPlayPlane战机小游戏
- 移臂调度算法java_C语言 磁盘调度模拟
- 小米杀不死的消息推送-- Android、java后端同时接入小米推送
- Linuc云面板---旗鱼云梯操作使用说明
- 图像处理与计算机视觉用c语言吗,即将不再只是图像的CVer,计算机视觉要变天...
- BLE 自适应跳频及算法实现
热门文章
- python airflow_1.airflow的安装
- alexa排名_PHP Alexa排名提取器类
- linux同步手机,Calabash+Gearman实现多手机同步测试机制
- 仲裁法院开庭:质证思路与如何进行开庭
- 十天学会Authorware6.5之第二天:交互
- css3vw适配_小tips:使用rem+vw实现简单的移动端适配
- profinet网关为何采用modbus协议转换?
- 几维安全等保2.0要点解析及落地实施技术攻略
- 形式参数和实际参数的区别
- cocos2dx3.17.2之梦幻西游开发日志(四)