1 为什么会出现引用?

在生活中,我们可能会给一些同学起外号,以“吴磊”同学为例,我们可以叫他“吴三石”,当我们叫到这个外号的时候就自然而然地想到“吴磊”同学,“吴三石”就是他的别名,而引用也可以这样简单理解:在语法层面上,引用就是取别名。

引用的出现是为了解决一些问题,主要包括:

● 避免拷贝构造函数创建临时对象所带来的开销。当将一个对象作为函数参数传递或返回时,如果使用传值方式,则会调用拷贝构造函数创建一个临时对象,这会带来额外的开销,而使用引用则可以避免这种开销。

● 让我们在函数内部修改传入的对象。如果不使用引用,则只能通过指针来实现这一点。

2 引用是什么?

在 C++ 中,引用是一种复合类型,它是一个对象的别名。引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共有一块内存空间。

语法格式:    类型 & 引用变量名(对象名) = 引用实体

例子:

int main(){//引用:取别名int a = 10;int& b = a;//定义引用类型int& c = b;return 0;
}

本段代码中,a 变量取了 b,c,可以通过调式观察它们的内存。

通过调取内存可以发现,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 &”

这是因为我们在引用的时候要遵守引用的规则:

引用规则:    对原变量的引用,权限不能放大

这段代码中 x 变量是 const 修饰的一个常变量,只有可读权限。而我们引用的类型是 int,不仅有可读权限,还有可修改权限。这就造成了对原变量的权限放大。根据我们引用原则知道,对原变量的引用,权限是不能放大的,这就是为什么这段代码会报错的原因。

那我们再来看这一段代码,他能否编译成功?

int main()
{//2.const int x = 20;const int& y = x;//不变//3.int c = 30;const int& d = c;//缩小return 0;
}

这段代码我们发现编译成功了,我们也可以轻松地分析出这里的引用是遵守引用规则的,我们发现,权限不变或者权限缩小都是符合规则的,唯一需要注意的是:权限不能放大。

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;
}

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;

然而,需要注意的是,对于一些内置类型以外的复合类型,如类或结构体,其引用的行为可能于内置类型有所不同。例如,如果我们在类中声明一个引用成员变量,那么这个引用变量实际上会占用一定的内存空间,因为引用本身需要在类中分配 空间。不过这种情况并不常见。

引用的底层实现通常是通过指针来实现的,而指针是需要占用内存空间的,因此,当我们使用引用时,实际上是在使用底层指针所指向的对象,而不是引用本身。在这种情况下,所占用的内存空间取决于所引用的对象的类型和 大小,而不是引用本身。

【基础知识】引用是什么?相关推荐

  1. [003]Reference in C++---C++引用基础知识篇

    最近在搞C++的引用,闲来无事,顺便写写引用的基础知识 引言:什么是引用 引用就是某一变量(目标)的一个别名,对引用的操作与对变量直接操作完全一样. 引用的格式: 数据类型 &引用变量名 = ...

  2. 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 ...

  3. java的一些基础知识(引用BlogJava 落花飞雪)

     java的一些基础知识(引用BlogJava 落花飞雪) <Practical Java>笔记 1. 声明是什么? String s = "Hello world!" ...

  4. python常用变量名_python基础知识整理

    Python Python开发 Python语言 python基础知识整理 序言:本文简单介绍python基础知识的一些重要知识点,用于总结复习,每个知识点的具体用法会在后面的博客中一一补充程序: 一 ...

  5. PHP内核介绍及扩展开发指南—基础知识

    一. 基础知识 本章简要介绍一些Zend引擎的内部机制,这些知识和Extensions密切相关,同时也可以帮助我们写出更加高效的PHP代码. 1.1 PHP变量的存储 1.1.1 zval结构 Zen ...

  6. ue4 函数和宏区别_【UE4】通俗易懂 用蓝图来学习 C++ 基础知识

    [前言]: 用老罗来学UE蓝图: https://zhuanlan.zhihu.com/p/135297007​zhuanlan.zhihu.com 再开个脑洞,用蓝图来类比学习C++基础知识. C+ ...

  7. SQL 数据完整性 基础知识

    数据完整性 基础知识 实体完整性<?XML:NAMESPACE PREFIX = O /> 实体完整性将行定义为特定表的唯一实体.实体完整性通过索引.UNIQUE 约束.PRIMARY K ...

  8. java基础知识点_「Java面试题/知识点精华集」20000+字的Java基础知识篇(2020最新版) !

    " 本文已经收录进我的 79K Star 的 Java 开源项目 JavaGuide:https://github.com/Snailclimb/JavaGuide (「Java学习+面试指 ...

  9. 计算机基础知识_2020年河北省高职单招计算机基础知识和实践技能培训

    本考纲是根据教育部2014年4月中华人民共和国教育部<中等职业学校专业教学标准(试行)>(教职成厅函[2014]11号)颁布的<中等职业学校计算机应用专业教学标准>.<中 ...

  10. 《Python基础知识全家桶》

    目录 1.实现一行输入多个数字,用空格隔开 2.实现一行输入多个单词,用","隔开 3.列表 4.for循环 5.切片 6.二维列表 7.元组 8.字典 set容器 9.嵌套 字典 ...

最新文章

  1. Java 线程池中的线程复用是如何实现的?
  2. es获取最大时间的记录_大屏幕大智慧,腕上私教+生理周期,荣耀手表ES评测
  3. 2.6 Go 读取CSV
  4. java 数据库连接池 开源_开源自己开发的一个JAVA数据库连接池,效果还算可以。...
  5. appium java 点击事件_java – 无法使用Appium在Android中的权限对话框中单击“允许”按钮...
  6. 不会诈骗的公司 都倒闭了
  7. 复制release文件到另一台电脑.exe文件无法运行_电脑技巧:电脑版微信双开(或微信多开)?用start指令可以解决...
  8. Anaconda jupyter-notebook 添加kernel
  9. traceroute tracert
  10. HR人力资源系统软件价格?哪家HR人力管理系统好
  11. 数学史思维导图_高中数学课堂教学中思维导图的制作运用
  12. postman(一)常用的Tests方法
  13. FPGA 频率计实验
  14. ubuntu16.04下安装录屏软件OBS studio
  15. AndroidPlayPlane战机小游戏
  16. 移臂调度算法java_C语言 磁盘调度模拟
  17. 小米杀不死的消息推送-- Android、java后端同时接入小米推送
  18. Linuc云面板---旗鱼云梯操作使用说明
  19. 图像处理与计算机视觉用c语言吗,即将不再只是图像的CVer,计算机视觉要变天...
  20. BLE 自适应跳频及算法实现

热门文章

  1. python airflow_1.airflow的安装
  2. alexa排名_PHP Alexa排名提取器类
  3. linux同步手机,Calabash+Gearman实现多手机同步测试机制
  4. 仲裁法院开庭:质证思路与如何进行开庭
  5. 十天学会Authorware6.5之第二天:交互
  6. css3vw适配_小tips:使用rem+vw实现简单的移动端适配
  7. profinet网关为何采用modbus协议转换?
  8. 几维安全等保2.0要点解析及落地实施技术攻略
  9. 形式参数和实际参数的区别
  10. cocos2dx3.17.2之梦幻西游开发日志(四)