【C++那些事儿】函数重载与C++中的“指针“——引用

在这里插入图片描述

君兮_的个人主页

即使走的再远,也勿忘启程时的初心

C/C++ 游戏开发

Hello,米娜桑们,这里是君兮_,我之前看过一套书叫做《明朝那些事儿》,把本来枯燥的历史讲的生动有趣。而C++作为一门接近底层的语言,无疑是抽象且难度颇深的。我希望能努力把抽象繁多的知识讲的生动又通俗易懂,因此,咱们这个讲解C++的系列博客就叫做《C++那些事儿》啦,而今天我们要讲的内容是C++中的函数重载与引用

  • 好了废话不多说,开始我们今天的学习吧!!

    C++那些事儿

    • 函数重载
      • 函数重载的概念
      • C++支持函数重载的原理--名字修饰(name Mangling)
    • 引用
      • 1.引用概念
      • 2.引用特性
      • 3.常引用
      • 4.引用的使用场景
        • (1).做函数的参数
        • (2).做返回值
      • 传值与传引用效率比较
      • 引用和指针的区别
    • 总结

函数重载

  • 说到函数重载,很多人不理解重载是什么意思,其实它就在我们身边,我来举个例子:
    在这里插入图片描述

一天,你的舍友有节课没去上课,但是碰巧老师上课点名点到他了,老师就问你:他来了吗?
你回答说:如来
老师又问你:到底来没来?
你回答说:如来
于是老师就把你请出教室了

  • 自然语言中,一个词可以有多重含义,人们可以通过上下文来判断该词真实的含义,即该词被重载了
  • 那在C++中什么是函数重载呢?

函数重载的概念

  • 函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这
    些同名函数的形参列表(参数个数 或 类型 或 类型顺序)不同,常用来处理实现功能类似数据类型
    不同的问题
#include<iostream>
using namespace std;// 1、参数类型不同
int Add(int x, int y)
{cout << "int类型的Add" <<" "<< x + y << endl;return x + y;
}
double Add(double x, double y)
{cout << "double类型的Add" << " " << x + y << endl;return x + y;
}
// 2、参数个数不同
void f()
{cout << "f()" << endl;
}
void f(int a)
{cout << "f(int a)" << endl;
}
// 3、参数类型顺序不同
void f(int a, char b)
{cout << "f(int a,char b)" << endl;
}
void f(char b, int a)
{cout << "f(char b, int a)" << endl;
}int main()
{int x = 0;int y = 0;Add(1, 5);f();f(10);f(10, 'b');f('a', 10);return 0;
}

在这里插入图片描述

  • 了解了函数重载的概念和基本使用方法后,很多人可能会想,为什么C++支持函数重载而C不支持函数重载呢?下面我们来讨论一下这个问题

C++支持函数重载的原理–名字修饰(name Mangling)

  • 在C/C++中,一个程序要运行起来,需要经历以下几个阶段:预处理、编译、汇编、链接。
    在这里插入图片描述
  • 这里对于没有接触过汇编语言以及编译链接的同学来说非常复杂,也不是我几句话就能说清楚的,因此大家简单理解记住结论即可,我也不会讲太深,随着之后我们C++之旅的进程,当我们接触到更多有关内容后,我再在合适的地方具体解释。
    在这里插入图片描述
  • 这张图片大概展示了在编译链接阶段各阶段进行的操作
  • 由于Windows下vs的修饰规则过于复杂,而Linux下g++的修饰规则简单易懂,我们通过在linux下编译后生成的汇编来讲解这部分内容
  • Linux环境下采用C语言编译器编译后结果
    在这里插入图片描述
  • 结论:在linux下,采用gcc编译完成后,函数名字的修饰没有发生改变
  • 采用C++编译器编译后结果
    在这里插入图片描述
  • 结论:在linux下,采用g++编译完成后,函数名字的修饰发生改变,编译器将函数参数类型信息添加到修改后的名字中

最终结论(在目前学习阶段记住这个结论就行)
1.C语言之所以没办法支持重载,是因为同名函数没办法区分。而C++是通过函数修饰规则来区分,只要参数不同,修饰出来的名字就不一样,就支持了重载。
2. 如果两个函数函数名和参数是一样的,返回值不同是不构成重载的,因为调用时编译器没办法区分。

引用

1.引用概念

  • 引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间
  • 在C++中,引用的作用类似于指针,但是它不开辟空间,在很多情况下,引用是比使用指针更好的选择。
  • 至于起别名,引用就相当于这个变量的外号一样
    比如 孙悟空,如果你是唐僧,你可以叫他悟空
    如果你是猪八戒或者沙僧,你可以叫他大师兄
    如果你是某地界的土地神,你可以叫他孙大圣
    如果你是他的死对头,你可以叫他泼猴或者弼马温…
  • 上述的这些,都是孙悟空的"引用:,也就是别名
    在这里插入图片描述
    类型& 引用变量名(对象名) = 引用实体;
void Test()
{int a = 10;int& ra = a;//<====定义引用类型printf("%p\n", &a);printf("%p\n", &ra);
}int main()
{Test();
}

在这里插入图片描述

  • 引用与原变量指向同一块空间

  • 注意:引用类型必须和引用实体是同种类型的

2.引用特性

  • 1. 引用在定义时必须初始化
  • 2. 一个变量可以有多个引用
  • 3. 引用一旦引用一个实体,再不能引用其他实体
void Test()
{int a = 10;int& ra = a;//<====定义引用类型int& b = a;//一个变量可以有多个别名printf("%p\n", &a);printf("%p\n", &ra);printf("%p\n", &b);
}

在这里插入图片描述

  • 多个引用仍然指向同一块空间
    在这里插入图片描述
  • 必须初始化,不然会报错

3.常引用

void TestConstRef()
{
const int a = 10;
//int& ra = a; // 该语句编译时会出错,a为常量
const int& ra = a;
}
  • 最常见的一种常引用,我们知道引用作为变量的别名,当改变引用的值时,是会改变变量的值的,因此当变量被const修饰时,它的引用也必须用const修饰
void TestConstRef()
{// int& b = 10; // 该语句编译时会出错,b为常量
const int& b = 10;
double d = 12.34;
//int& rd = d; // 该语句编译时会出错,类型不同
const int& rd = d;
}
  • 当我们直接吧一个常量给一个引用时,必须加const,原因与第一种情况相同,而常量就更不可能让你通过引用来修改它的值了
void TestConstRef()
{
double d = 12.34;
//int& rd = d; // 该语句编译时会出错,类型不同
const int& rd = d;
}
  • 这里是存在一个类型的隐式转换的,把double类型的转换成int型,这里类型发生了转换,因此我们也不能通过别名来修改变量,因此必须加const

4.引用的使用场景

(1).做函数的参数

void Swap(int& left, int& right)
{
int temp = left;
left = right;
right = temp;
}
  • 和指针在这里的使用方法是类似的,就不过多展开了

(2).做返回值

int& Count()
{
static int n = 0;
n++;
// ...
return n;
}

注意:如果函数返回时,出了函数作用域,如果返回对象还在(还没还给系统),则可以使用引用返回,如果已经还给系统了,则必须使用传值返回。

  • 下面我们来看一个例子
int& Add(int a, int b)
{
int c = a + b;
return c;
}
int main()
{
int& ret = Add(1, 2);
Add(3, 4);
cout << "Add(1, 2) is :"<< ret <<endl;
return 0;
}

在这里插入图片描述

  • 因此,当我们运行时出现这种结果,也就不奇怪了
    在这里插入图片描述
  • 那应该怎么解决上述的这种问题呢?
  • 很简单,我们让函数解释时,不会释放申请的空间就好了
int& Add(int a, int b)
{static int c = a + b;return c;
}
int main()
{int& ret = Add(1, 2);Add(3, 4);cout << "Add(1, 2) is :" << ret << endl;return 0;
}

在这里插入图片描述

传值与传引用效率比较

  • 以值作为参数或者返回值类型,在传参和返回期间,函数不会直接传递实参或者将变量本身直接返回,而是传递实参或者返回变量的一份临时的拷贝,因此用值作为参数或者返回值类型,效率是非常低下的,尤其是当参数或者返回值类型非常大时,效率就更低。
  • 总的来说,你在这里可以暂时把引用类比成指针来使用,等之后学习了类和对象之后,才能更加明白引用在使用时候的妙处

引用和指针的区别

  • 在语法概念上引用就是一个别名,没有独立空间,和其引用实体共用同一块空间。
  • 在底层实现上实际是有空间的,因为引用是按照指针方式来实现的。
int main()
{//int& ret = Add(1, 2);char c = 'a';char& rc = c;char* rrc = &c;cout << "&rc"<<" "<< sizeof(c) << endl;cout << "rrc" <<" "<< sizeof(rrc) << endl;return 0;
}

在这里插入图片描述

  • 在这里编译器告诉我们引用占一个字节,而指针占8个字节,可事实真的如此吗?
    在这里插入图片描述
  • 通过底层的汇编代码,我们可以知道,实际上,引用是按指针方式实现的是占空间的,至于为什么编译器告诉你它不占空间,因为在C++规定时说引用是一个别名是不占空间的,它总不能自己打自己脸呀
    在这里插入图片描述

引用与指针的其他区别点

1. 引用概念上定义一个变量的别名,指针存储一个变量地址。
2. 引用在定义时必须初始化,指针没有要求
3. 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何
一个同类型实体
4. 没有NULL引用,但有NULL指针
5. 在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32
位平台下占4个字节)
6. 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小
7. 有多级指针,但是没有多级引用
8. 访问实体方式不同,指针需要显式解引用,引用编译器自己处理
9. 引用比指针使用起来相对更安全


总结

  • 好啦,我们今天的内容就先到这里啦!今天讲解了函数重载与引用使用方法以及有关它们使用的细节和注意事项,这两块的知识点会一直伴随你C++学习之路,是非常重要的,因此希望大家把有关的重点和难点多看几遍加深理解。

  • 有任何的问题和对文章内容的疑惑欢迎在评论区中提出,当然也可以私信我,我会在第一时间回复的!!

新人博主创作不易,如果感觉文章内容对你有所帮助的话不妨三连一下再走呗。你们的支持就是我更新的动力!!!

**(可莉请求你们三连支持一下博主!!!点击下方评论点赞收藏帮帮可莉吧)**

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/169240.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PDF Reader Pro v2.9.8(pdf编辑阅读器)

PDF Reader Pro是一款PDF阅读和编辑软件&#xff0c;具有以下特点&#xff1a; 界面设计简洁&#xff0c;易于上手。软件界面直观清晰&#xff0c;用户可以轻松浏览文档&#xff0c;编辑注释和填写表单。功能强大&#xff0c;提供了多种PDF处理工具&#xff0c;包括阅读、注释…

保护公司数据安全的措施

保护公司数据安全的措施 互联网时代&#xff0c;数据安全对企业而言是非常重要的&#xff0c;数据是每个组织的命脉&#xff0c;保护好数据安全企业才能稳定长久的发展下去&#xff0c;很多企业就是因为不重视数据安全防护&#xff0c;导致数据泄露从而遭受了很大的损失。因此…

吃瓜教程2|线性模型

线性回归 “广义的线性模型”&#xff08;generalized linear model&#xff09;&#xff0c;其中&#xff0c;g&#xff08;*&#xff09;称为联系函数&#xff08;link function&#xff09;。 线性几率回归&#xff08;逻辑回归&#xff09; 线性判别分析 想让同类样本点的…

MySQL -- 库和表的操作

MySQL – 库和表的操作 文章目录 MySQL -- 库和表的操作一、库的操作1.创建数据库2.查看数据库3.删除数据库4.字符集和校验规则5.校验规则对数据库的影响6.修改数据库7.备份和恢复8.查看连接情况 二、表的操作1.创建表2.查看表结构3.修改表4.删除表 一、库的操作 注意&#xf…

LeetCode2409——统计共同度过的日子数

博主的解法过于冗长&#xff0c;是一直对着不同的案例debug修改出来的&#xff0c;不建议学习。虽然提交成功了&#xff0c;但是自己最后都不知道写的是啥了哈哈哈。 package keepcoding.leetcode.leetcode2409; /*Alice 和 Bob 计划分别去罗马开会。给你四个字符串 arriveA…

分类预测 | MATLAB实现SSA-CNN-GRU麻雀算法优化卷积门控循环单元数据分类预测

分类预测 | MATLAB实现SSA-CNN-GRU麻雀算法优化卷积门控循环单元数据分类预测 目录 分类预测 | MATLAB实现SSA-CNN-GRU麻雀算法优化卷积门控循环单元数据分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述 1.MATLAB实现SSA-CNN-GRU麻雀算法优化卷积门控循环单元数据…

访问控制2

文章目录 主要内容一.Role和ClusterRole1.ClusterRole示例&#xff0c;创建一个名为test-clusterrole且仅有创建Pod和deployment的集群角色代码如下&#xff08;示例&#xff09;: 2.YAML文件创建代码如下&#xff08;示例&#xff09;: 3.将udbs用户和Clusterrole进行绑定&…

032-第三代软件开发-Popup弹窗

第三代软件开发-Popup弹窗 文章目录 第三代软件开发-Popup弹窗项目介绍Popup弹窗官方示例项目中的代码 之前写过一个Popup抄抄别人的dimvisible 和 Open 区别 与 Dialog有啥区别其他总结一下 关键字&#xff1a; Qt、 Qml、 Popup、 弹窗、 modal 项目介绍 欢迎来到我们的…

【计算机网络】TCP 协议的相关特性

TCP&#xff08;传输控制协议&#xff09;是一种面向连接的、可靠的、基于字节流的协议。以下是TCP协议的相关特性&#xff1a; 可靠性&#xff1a;TCP通过确认和重传机制保证数据的可靠传输。 面向连接&#xff1a;TCP在传输数据前需要先建立连接。连接的建立过程包括三次握手…

号外!百度Comate代码助手全新上线SaaS服务 - 免费申请试用+深入教程解读!

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

专业软件测评中心分享:科技成果验收测试报告的作用

科技成果验收测试是科技项目在开发完成后进行的一项测试&#xff0c;旨在检测科技项目的成果是否符合预期的技术指标和效果&#xff0c;以及是否符合用户需求和行业标准。验收测试报告是科技成果验收的重要依据&#xff0c;用于记录和证明科技成果的测试结果和性能表现。 一、…

Java入门讲解(1)---让你瞬间明白如何安装jdk

博主有话说&#xff1a;学习这个东西一定要持之以恒&#xff01;&#xff01;&#xff01;博主之前因为点事情半个月没学习&#xff0c;重新来过时&#xff0c;发现自己错过好多知识&#xff0c;正在一点一点往回补&#xff0c;博客也会陆续开始更新&#xff0c;希望大家多多支…

安防视频监控平台EasyCVR新版(V.3.4)平台界面更新2.0

视频监控TSINGSEE青犀视频平台EasyCVR能在复杂的网络环境中&#xff0c;将分散的各类视频资源进行统一汇聚、整合、集中管理&#xff0c;在视频监控播放上&#xff0c;TSINGSEE青犀视频安防监控汇聚平台可支持1、4、9、16个画面窗口播放&#xff0c;可同时播放多路视频流&#…

Mask Free VIS笔记(CVPR2023 不需要mask标注的实例分割)

paper: Mask-Free Video Instance Segmentation github 一般模型学instance segmentation都是要有mask标注的&#xff0c; 不过mask标注既耗时又枯燥&#xff0c;所以paper中仅用目标框的标注来实现实例分割。 主要针对视频的实例分割。 之前也有box-supervised实例分割&…

MySQL执行计划分析

执行计划中的常见的列的解释&#xff1a; type system/const &#xff1a;用户主键索引或者唯一索引查询时&#xff0c;只能匹配 1 条数据。一般可以对 sql 查询语句优化成一个常量&#xff0c;那么 type 一般就是 system 或者 const&#xff0c;system 是 const 的一个特例&…

网络安全—自学笔记

目录 一、自学网络安全学习的误区和陷阱 二、学习网络安全的一些前期准备 三、网络安全学习路线 四、学习资料的推荐 想自学网络安全&#xff08;黑客技术&#xff09;首先你得了解什么是网络安全&#xff01;什么是黑客&#xff01; 网络安全可以基于攻击和防御视角来分类…

VSCode安装使用(含插件保姆级教程)

前言 工欲善其事&#xff0c;必先利其器 对于我们每一位软件工程师来说&#xff0c;都要有自己顺手的 IDE 开发工具&#xff0c;它就是我们的武器。 一个好用的 IDE 不仅能提升我们的开发效率&#xff0c;还能让我们保持愉悦的心情&#xff0c;这样才是非常 Nice 的状态 &…

unity游戏画质设置功能实现

在游戏中往往会出现游戏画质设置的功能。 如图&#xff1a; 这个功能是怎么实现完成的呢&#xff1f; 一、目标&#xff1a;实现切换画质功能 二、了解unity支持的画质 首先要了解unity中共支持多少种画质。 在代码中也可以进行打印。 方法如下&#xff1a; void Start …

大河弯弯:CSS 文档流与三大元素显示模式

文章目录 参考环境文档流概念三大显示模式 内联元素概念常见的内联元素宽高由内容决定 块级元素概念常见的块级元素宽度受容器影响&#xff0c;高度受内容影响 内联块级元素概念常见的内联块级元素折中方案 设置元素的显示模式display 属性内联元素与块级元素的切换为什么要通过…

【CSS】常见 CSS 布局

1. 响应式布局 <!DOCTYPE html> <html><head><title>简单的响应式布局</title><style>/* 全局样式 */body {font-family: Arial, sans-serif;margin: 0;padding: 0;}/* 头部样式 */header {background-color: #333;color: #fff;padding: …