【C++】掌握C++函数重载和引用开启代码优化的新篇章

欢迎来CILMY23的博客

本篇主题为 掌握C++函数重载和引用开启代码优化的新篇章

个人主页:CILMY23-CSDN博客

个人专栏:   |  |  | CILMY23-CSDN博客

上一篇博客:第一个C++结构,C++关键字,命名空间,C++的输入输出,缺省参数

感谢观看,支持的可以给个一键三连,点赞关注+收藏。


目录

 一、 函数重载

1.1 函数重载的概念

1.2 cpp是如何支持重载的呢? 

1.3 Linux -- gcc 编译器下的规则

1.4 Visual Studio 2019 的命名规则

二、 引用

2.1 引用概念

2.2 引用的用法 

2.3 引用的特点

2.4 引用的应用1 --- 做参数 

 2.5 引用不能代替指针的原因

2.6 引用的应用2 --- 做返回值

2.7 引用和指针的区别 

2.8 引用和指针的不同


本文前言

上一篇简要介绍了C++编程语言的初级概念。我们学习了C++的程序结构和基本语法,了解了关键字的作用和用法。通过命名空间,我们可以避免命名冲突,并组织代码。使用cin和cout进行输入输出操作,方便与用户交互。缺省参数可以使函数调用更灵活。通过学习,我们打下了C++编程的基础。接下来,我们将继续学习重点知识 --- 函数重载


 一、 函数重载

在过去我们学习C语言的时候通常都会碰到一个问题,我们定义函数的时候是不让同名的,也就是ADD函数只有一个,所以我们为了方便起见通常用一个宏来定义一个type,这样方便修改函数的数据类型,而在C++中,我们引入了函数重载的概念,它允许函数同名,但要求参数不同

1.1 函数重载的概念

函数重载是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数或类型或类型顺序)不同,常用来处理实现功能类似数据类型不同的问题

 函数重载一共有三种方式:

1.函数参数的数据类型不同

2.函数参数的顺序不同

3.函数参数的个数不同

//函数重载
//1.函数参数的数据类型不同
int Add(int a, int b)
{cout << "this is int Add" << endl;return a + b;
}double Add(double a, double b)
{cout << "this is double Add" << endl;return a + b;
}
//2.函数参数的顺序不同
void A(int a, char b)
{cout << "void A(int a, char b)" << endl;
}void A(char b, int a)
{cout << "void A(char b, int a)" << endl;
}
//3.函数参数的个数不同
void f()
{cout << "void f()" << endl;
}void f(int a)
{cout << "void f(int a)" << endl;
}

注意:函数重载不能依靠返回值的不同来构成重载,因为调用时无法根据参数列表确定调用哪个重载函数 

例如:double Add() 和int Add()不能构成重载函数。

1.2 cpp是如何支持重载的呢? 

在C语言中,我们的C是直接通过函数名去找地址的,所以它不支持重载的原因是同名函数不知道该找谁的地址。

那我们知道从编译到可执行程序需要经历四个阶段,预编译,编译,汇编,链接(第一个C++结构,C++关键字,命名空间,C++的输入输出,缺省参数)

那C++是如何支持的呢?我们引入了一个规则 --- 函数名修饰规则, 我们不是要通过函数名来查找函数地址吗,那如果函数名的修饰再加上参数以及其他的一些符号,这样通过不同函数名和不同的参数就能确定一个唯一的地址。

但是并没有很强制的规定,所以各个编译器都自己实现了一套命名规则。 

1.3 Linux -- gcc 编译器下的规则

在gcc当中,它们的命名方式比较简约。

_Z + 函数名称长度 + 函数名称 + 参数类型首字母

1.4 Visual Studio 2019 的命名规则

当我们声明和定义分离的时候,把定义部分去掉,就可以在Visual 的窗口中看到报错

当我们写很多种的函数就可以总结一个规律

visual 的修饰 (?+ 函数名称 + @@YA + 参数类型 + @Z) 

二、 引用

2.1 引用概念

引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空 间,它和它引用的变量共用同一块内存空间。

2.2 引用的用法 

引用的语法如下:

类型&  对象名 = 引用实体 

 例如:

//引用int main()
{int a = 0;int& b = a;int& c = b;cout << b << endl;a++;cout << b << endl;b++;cout << c << endl;}

结果:输出0,1,2 

b 就是 a ,别名是可以无限取的,就跟人的名字一样,有无数外号,别名也可以有别名。

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

2.3 引用的特点

1. 引用在定义时必须初始化
2. 一个变量可以有多个引用
3. 引用一旦引用一个实体,再不能引用其他实体

错误1: 

int a = 10;
int& ref;  // 无法通过编译,因为ref没有进行初始化

错误2: 

int a = 10;
int b = 20;
int& ref = a; // ref现在引用a
int& rref = a; 

 

2.4 引用的应用1 --- 做参数 

过去我们在C语言中,要交换两个变量的值,通常用函数+指针+额外变量来进行交换,现在我们可以用引用来处理。

//引用特点  --- 做函数参数
void Swap(int* a, int* b)
{int tmp = *a;*a = *b;*b = tmp;
}void Swap(int& a, int& b)
{int tmp = a;a = b;b = tmp;
}int main()
{int n1 = 10;int n2 = 20;Swap(n1, n2);
}

Swap函数使用的是引用参数,对a和b的操作会直接影响到n1,n2,不需要额外开辟空间。 

参数也分两种(a.输出型参数b.是对象比较大,减少拷贝提高效率) 

 2.5 引用不能代替指针的原因

 指针和引用的功能有部分是类似的,有些复杂场景是可以替代的,但是不能完全替代指针。

 引用不能完全替代指针的原因:引用定义后,不能改变指向

2.6 引用的应用2 --- 做返回值

 我们在调用函数的时候,出了函数作用域的东西,就可能会出现随机值,

int fun1()
{int a = 0;return a;
}int main()
{int ret = fun1();return 0;
}

传值返回的函数,ret就是读取不到a,函数会临时拷贝a的值存在寄存器中然后将a的值返回。

但函数也可以传引用,像以下情况就不行

int& fun1()
{int a = 0;return a;
}int main()
{int ret = fun1();cout << ret << endl;return 0;
}

 但是这里会报错,,这里栈帧没清,所以值是0,也因此值在不同平台是不同的,

如果函数返回时,出了函数作用域,如果返回对象还在(还没还给系统),则可以使用引用返回,例如:全局变量,静态变量,堆上变量等,如果已经还给系统了,例如:局部变量,则必须使用传值返回。

2.7 引用和指针的区别 

 在语法概念上引用就是一个别名,没有独立空间,和其引用实体共用同一块空间。在底层实现上实际是有空间的,因为引用是按照指针方式来实现的。

int main()
{int a = 10;int& ra = a;ra = 20;int* pa = &a;*pa = 20;return 0;
}

 汇编代码的对比:

引用和指针的效率对比:

#include <time.h>
struct A { int a[10000]; };
A a;
// 值返回
A TestFunc1() { return a; }
// 引用返回
A& TestFunc2() { return a; }
void TestReturnByRefOrValue()
{// 以值作为函数的返回值类型size_t begin1 = clock();for (size_t i = 0; i < 100000; ++i)TestFunc1();size_t end1 = clock();// 以引用作为函数的返回值类型size_t begin2 = clock();for (size_t i = 0; i < 100000; ++i)TestFunc2();size_t end2 = clock();// 计算两个函数运算完成之后的时间cout << "TestFunc1 time:" << end1 - begin1 << endl; cout << "TestFunc2 time:" << end2 - begin2 << endl;
}

结果如下; 

 

2.8 引用和指针的不同

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


 感谢各位同伴的支持,本期C++入门篇就讲解到这啦,如果你觉得写的不错的话,可以给个一键三连,点赞关注+收藏,若有不足,欢迎各位在评论区讨论。    

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

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

相关文章

IPEX-LLM(原名BigDL-LLM)环境配置

IPEX-LLM 是一个为Intel XPU (包括CPU和GPU) 打造的轻量级大语言模型加速库&#xff0c;在Intel平台上具有广泛的模型支持、最低的延迟和最小的内存占用。 您可以使用 IPEX-LLM 运行任何 PyTorch 模型&#xff08;例如 HuggingFace transformers 模型&#xff09;。在运行过程中…

《C++程序设计》阅读笔记【7-堆和拷贝构造函数】

&#x1f308;个人主页&#xff1a;godspeed_lucip &#x1f525; 系列专栏&#xff1a;《C程序设计》阅读笔记 本文对应的PDF源文件请关注微信公众号程序员刘同学&#xff0c;回复C程序设计获取下载链接。 1 堆与拷贝构造函数1.1 概述1.2 分配堆对象1.3 拷贝构造函数1.3.1 默…

301永久重定向与302临时重定向的正确运用

我们前不久有Hostease的客户的网站进行了域名更改。客户想了解域名更改后会有哪些后果和影响。一般网站域名更换后会遇到旧页面失效问题。为了优化用户体验和维护搜索引擎优化(SEO)&#xff0c;我们需要正确地使用301永久重定向和302临时重定向。这两种重定向方式各有其特点和适…

本地linux怎样先亚马逊云服务器上传文件

使用亚马逊云服务器的密钥&#xff0c;并通过srp命令&#xff0c; 连接上传&#xff1a; scp -i <密钥文件路径> <本地文件路径> <远程主机用户名><远程主机地址>:<目标路径> scp -i assig2.pem data.txt ubuntuec2-xx-xxx-xx-xx1.compute-x.…

langchain 使用本地通义千问

langchian 使用已经下载到本地的模型&#xff0c;我们使用通义千问 显存&#xff1a;24G 模型&#xff1a;qwen1.5-7B-Chat&#xff0c;qwen-7B-Chat 先使用 qwen-7B-Chat&#xff0c;会报错用不了&#xff1a; 看了下是不支持这中模型&#xff0c;但看列表中有一个 Qwen 字样…

【Linux】初识Linux,虚拟机安装Linux系统,配置网卡

前言 VMware软件&#xff1a;首先&#xff0c;确保您已经下载了VMware Workstation软件并安装在电脑上。VMware Workstation是一款功能强大的虚拟化软件&#xff0c;它允许在单一物理机上运行多个操作系统。 Linux镜像文件&#xff1a;需要准备一个Linux操作系统的镜像文件。…

python使用uiautomator2操作雷电模拟器9找图

接上篇文章python使用uiautomator2操作雷电模拟器9并遇到解决adb 连接emulator-5554 unauthorized问题-CSDN博客 搭建好uiautomator2后&#xff0c;主要就是使用了。 本文就利用uiautomator2的截屏、模拟点击和aircv的找图功能&#xff0c;实现对指定寻找的图片的位置的点击。…

java程序生成exe文件启动时,在没有java环境计算机运行

1.idea项目配置工件 2. 开始构建java程序成jar包 3. 生成exe启动程序

结构型模式--3.组合模式【草帽大船团】

1. 好大一棵树 路飞在德雷斯罗萨打败多弗朗明哥之后&#xff0c;一些被路飞解救的海贼团自愿加入路飞麾下&#xff0c;自此组成了草帽大船团&#xff0c;旗下有7为船长&#xff0c;分别是&#xff1a; 俊美海贼团75人 巴托俱乐部56人 八宝水军1000人 艾迪欧海贼团4人 咚塔塔海…

交换机的基本原理与配置_实验案例一:交换机的初始配置

1、实验环境 实验用具包括一台Cisco交换机&#xff0c;一台PC&#xff0c;一根Console 线缆。 2、需求描述 如图5.17所示&#xff0c;实验案例一的配置需求如下。 通过PC连接并配置一台Cisco交换机。在交换机的各个配置模式之间切换。将交换机主机的名称改为BDON 3、推荐步…

知网参考文献引用格式转latex中BibTex-Python操作

处理思路 参考 处理步骤&#xff1a; &#xff08;单条处理&#xff1a;&#xff09; 1、选知网NoteExpress格式的2-7行复制信息 2、新建一个文本文件&#xff0c;命名为cite.txt&#xff0c;把知网所复制信息粘贴进来 &#xff08;txt文件保存编码ANSI可行&#xff09; 3、…

Double.toString()原理

转变过程 如图&#xff0c;假设将double类型能精确表示的数字落在数轴上&#xff0c;分别是double1、double2、double3。 这个时候&#xff0c;我们有十进制数字a&#xff0c;想要转变成double表示&#xff0c;这个时候得到的是double2&#xff0c;因为double2是距离这个十进制…

进制转换(2 8 10 16 String)

题目 public class Main {static String s "0123456789abcdef";//m 2 8 10 16public static int res(int n,int m) {StringBuffer sb new StringBuffer(); while(n!0) {sb.append(s.charAt(n%m));n/m;}//转换为对应进制之后String s sb.reverse().toString();ch…

2023NJU-ICS PA1.2表达式求值 思路详解 心得体会

前言 PA1.2的细节非常非常多&#xff0c;导致这几天花了大量的时间去调试bug&#xff0c;4.3晚上终于过了最后一关“如何测试你的代码”&#xff08;花了两整天时间才调成功&#xff09;。虽然耗时巨大&#xff0c;但确实学到了不少东西、训练了能力&#xff0c;于是抽几天时间…

echarts地图自定义label属性以及引入china.js

效果图: 要点1:calc函数 重点&#xff1a;在于mapChart的height可以写成函数以便适配不同尺寸&#xff1b; <div class"content-map"><div class"wai-top-box" style"width: 100%; height: 100%"><div id"mapChart" s…

Host Aware SMR

SMR 简介 首先给一点前置SMR知识。 SMR优势&#xff1a;Capacity的提升。 看图&#xff1a;由于重叠Track使得存储密度得到了提升。但是由于Track的重叠&#xff0c;使得SMR只能顺序写。 在SMR中&#xff0c;多个Track组成一个Band&#xff0c;各个Band之间可以随机写 这个 …

94岁诺奖得主希格斯去世,曾预言「上帝粒子」的存在

ChatGPT狂飙160天&#xff0c;世界已经不是之前的样子。 新建了免费的人工智能中文站https://ai.weoknow.com 新建了收费的人工智能中文站https://ai.hzytsoft.cn/ 更多资源欢迎关注 一位用诗意的语言揭示宇宙秘密的人。 一位 94 岁伟大科学家的逝世&#xff0c;引发了人们广泛…

RUST语言值所有权之内存复制与移动

1.RUST中每个值都有一个所有者,每次只能有一个所有者 String::from函数会为字符串hello分配一块内存 内存示例如下: 在内存分配前调用s1正常输出 在分配s1给s2后调用报错 因为s1分配给s2后,s1的指向自动失效 s1被move到s2 s1自动释放 字符串克隆使用 所有整数类型,布尔类型 …

nandgame中的Code generation(代码生成)

题目说明&#xff1a; 代码生成为语言的语法规则定义代码生成&#xff0c;以支持加法和减法。 您可以使用在前面级别中定义的堆栈操作&#xff08;如ADD和SUB&#xff09;。代码生成模板通常需要包含规则中其他符号的代码。 这些可以通过方括号中的符号名称插入。例如&#xf…

day03-java类型转换和运算符

3.1 表达式和语句 表达式一共分为三种&#xff1a; &#xff08;1&#xff09;变量或常量 运算符构成的计算表达式 &#xff08;2&#xff09;new 表达式&#xff0c;结果是一个数组或类的对象。&#xff08;后面讲&#xff09; &#xff08;3&#xff09;方法调用表达式&…