【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;。在运行过程中…

TTL接口的输入输出

The Ins and Outs of the TTL Interface 串行通信可在相当长的距离内传输数据&#xff0c;通常与 TTL 标准有关。数据通过串行通信传输&#xff0c;串行通信通过单线传输比特位。数据通过双方--发送方和接收方--以二进制脉冲的形式使用各种串行数字二进制技术进行交换。 RS232 …

jquery按回车切换下一个文本框

/** *按回车切换下一个文本框 *param field *param event *returns Boolean *οnkeypress"return handleEnter(this,event)" */ function handleEnter(field,event){ var keyCode event.keyCode ? event.keyCode : event.which ? event.which :event.ch…

Sql缺失索引查询,自动创建执行语句

试图查询确实的索引 CREATE VIEW [dbo].[vw_Index_MissingIndex] ASSELECT [ d.name ] as DBName,[dbo].[fn_Index_CreateIndexName](mid.equality_columns,mid.Inequality_columns,mid.index_handlE) AS ID,REPLACE(mid.equality_columns,,, ASC,) AS equality_columns,REP…

Redis面试题1

Redis基础概念 1.请简述Redis是什么&#xff1f; 答&#xff1a;Redis是一个开源的使用ANSI C语言编写的、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库&#xff0c;并提供多种语言的API。它通常被称为数据结构服务器&#xff0c;因为值&#xff0…

《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.…

用c++做到将数字转换为中文模式

主要功能就是将数字的123&#xff0c;个位&#xff0c;十位&#xff0c;百位知道亿都用中文给显示出来 具体代码如下&#xff1a; #include <iostream> #include <string> using namespace std; // 定义数字对应的中文字符 const string zw[] { "零"…

面向对象编程:在Python中的面向对象编程奥秘

面向对象编程在Python中的奥秘 在编程的世界里&#xff0c;面向对象编程&#xff08;Object-Oriented Programming&#xff0c;简称OOP&#xff09;是一种非常重要的编程范式。它改变了我们思考问题和设计代码的方式。Python作为一种支持面向对象的语言&#xff0c;为我们提供…

langchain 使用本地通义千问

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

谷歌(Google)技术面试——在线评估问题(二)

谷歌&#xff08;Google&#xff09;面试过程的第一步&#xff0c;你可能会收到一个在线评估链接。 评估有效期为 7 天&#xff0c;包含两个编码问题&#xff0c;需要在一小时内完成。 以下是一些供你练习的在线评估问题。 在本章结尾处&#xff0c;还提供了有关 Google 面试不…

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

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

win64平台用cmake编译lvgl

一、编译步骤 1&#xff0c;配置 mkdir build cd build 配置release&#xff0c;动态库 cmake .. -G"Visual Studio 17 2022" -DCMAKE_BUILD_TYPERelease -DCMAKE_INSTALL_PREFIXinstall -DBUILD_SHARED_LIBSON -DCMAKE_WINDOWS_EXPORT_ALL_SYMBOLSON -DLV_CO…

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启动程序

【图像分类】MMPretrain训练ImageNet格式自定义数据集

1. 安装环境 1.1. Conda虚拟环境 conda create --name mmpretrain python3.8 -y conda activate mmpretrain 1.2. 安装PyTorch pip install torch1.13.1cu117 torchvision0.14.1cu117 torchaudio0.13.1 --extra-index-url https://download.pytorch.org/whl/cu117 1.3. 安…

结构型模式--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、推荐步…

滴滴春招内幕揭秘:2024最全Spring JPA面试题大全,含详解与实战示例!百分之九十九的Java后端开发者都在收藏!

在2024年的技术招聘市场中&#xff0c;滴滴出行作为领先的移动出行平台&#xff0c;对后端开发人员的需求依然强劲。随着Spring框架在企业级Java应用开发中的广泛应用&#xff0c;Spring Data JPA作为数据访问层的关键技术&#xff0c;成为了滴滴面试中的重要考察点之一。Sprin…