C++函数重载及引用

news2024/11/30 12:45:12

应知学问难,在于点滴勤

在这里插入图片描述

 C++和C语言函数之间最大的的不同是C++支持缺省参数,而C语言不支持,这里我使用的编译器为VS2022,创建项目时是依据文件后缀判断该文件为C文件还是C++。(编译环境VS2022)

文章目录

      • 缺省参数
      • 函数重载
      • 引用
      • 引用特性模拟
      • 效率比较
      • 引用和指针的不同
      • 内联函数

缺省参数

C::
在这里插入图片描述
C++::
在这里插入图片描述
可以发现在C++文件下并没有报错,这里输出的结果是多少呢?
在这里插入图片描述
如果没有传入参数呢?
在这里插入图片描述
正式介绍一下
缺省参数:在声明或定义时为函数的参数设置一个缺省值,在调用该函数时,如果没有指定实参择采用该形参的缺省值,负责使用指定的实参。
缺省参数也有分类

  • 全缺省参数

就像上边的一样,每个形参都有一个设置的缺省值。

void Perform(int x=1, double d=2.5, char c='d')
{
	cout << x << endl;
	cout << d << endl;
	cout << c << endl;
}
  • 半缺省参数
void Perform(int x, double d=2.5, char c='d')
{
	cout << x << endl;
	cout << d << endl;
	cout << c << endl;
}

 半缺省参数只能从右往左给,第一个可以不给,第一个第二个都可以不给,但是不能单独第二个不给,不然就会报错。
在这里插入图片描述
如果第一个第二个都不给就可以运行。
在这里插入图片描述
在设置缺省值时不可以声明和定义时一起给。
在这里插入图片描述
 这里推荐在声明时给出缺省值,因为如果声明和定义都出现了缺省参数,有一些小马虎给定义和声明的缺省参数不一样,这时编译器就难过了,不知道到底该用哪个作为真实值,为了杜绝这个问题的发生,编译器就只允许在声明和定义时只有其中一个给缺省参数,至于为什么推荐在声明时定义,是为了更好地寻找并了解我们缺省参数的信息。
OK,成功引出了函数重载

函数重载

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

  • 数据类型不同
int Add(int x, int y)
{
	return x + y;
}
double Add(double x, double y)
{
	return x + y;
}
  • 个数不同
int Add(int x, int y)
{
	return x + y;
}
int Add(int x)
{
	cout << x << endl;
}
  • 参数类型排序不同
double Add(double x, int y)
{
	return x + y;
}
double Add(int x,double y)
{
	return x + y;
}

一定要注意:
返回值不同不能作为重载条件!!!

引用

引用的概念:引用不是新定义一个变量,而是给已经存在的变量取一个别名,就类似于现实生活中给小明起外号叫鸡哥,鸡哥是他,小明也是他。编译器不会为引用变量开辟内存空间,他和他引用的变量占用同样的空间。
 是不是刹那间觉得好生熟悉,其实引用就是替代某些情况下指针的作用,而且它的底层实现其实就是指针,同一个变量可以有多个指针,当然,同一个变量可以有很多引用。
引用格式:

类型& 引用变量名(对象名)=引用实体;

在这里插入图片描述
要注意:引用类型必须和引用实体的类型相同。

引用特性

  • 使用引用定义时必须初始化。
  • 一个变量可以有多个引用。
  • 引用一旦引用一个实体,就不能再引用其他实体,就像在班级里,一个boy的外号叫黑旋风,黑旋风这个外号就属于他了,如果还有人叫黑旋风,当你在班级里喊一声黑旋风,他们就不知道到底喊得那个黑旋风了。

在这里插入图片描述
 但是一个小伙可以有多个引用,就比如小明,有了鸡哥的外号后,又被赋予坤坤的外号,那么坤坤是他,鸡哥也是他,所以一个变量可以有多个引用,每个引用其实还是他自己。
在这里插入图片描述
这里还有一点要注意
引用的类型要和变量的类型一致,如果变量是常性的,那么引用就也要用const修饰。
在这里插入图片描述
 因为const修饰a之后,a变量不可以被修改,此时引用变量不加const的话,局可以通过引用修改a的值,这不就矛盾了。所以在引用常变量时,也要用const修饰。
 如果变量a没有用const修饰,引用用const修饰,这样是可以的,一句话来讲就是不可以扩大权限,但可以缩小权限

引用特性模拟

 相信大家都知道,函数传参并不是真的把变量传过去,而是生成相应的形参,然而形参改变不影响实参,在C语言时,我们利用指针传参,将数据的地址传过去,从而改变实参,现在,有了引用,就可以不必这么麻烦了。
我们直接引用接收,此时形参就是实参的引用,引用改变就会改变实参。
举一个最直观的例子。
在这里插入图片描述
是不是十分方便。
引用还可以用作返回值。
例如
在这里插入图片描述
 是不是觉得有点不对,我们传回来的值是一个临时变量,所以需要传回来的值用static修饰,延长其作用周期。防止退栈后这块内存还给操作系统从而得到的数为随机数值。

效率比较

传值传引用效率比较
以值作为参数或者返回值类型,在传参和返回期间,函数不会直接传递实参或者将变量本身传过去,而是生成一份实参或返回值的一份临时的拷贝,用这个临时拷贝的值作为参数或者返回值,这样效率是十分低下的,尤其是当参数或者返回值很大时,创建临时变量也会花费不少的时间,效率就会更加低下。
验证:

#include <time.h>
#include <iostream>
using namespace std;
struct A
{
	int a[100000];
};

void TestFunc1(A a){}
void TestFunc2(A& a){}
void Test()
{
	A a;
	size_t begin1 = clock();
	for (size_t i = 0; i < 100000; i++)
	{
		TestFunc1(a);
	}
	size_t end1 = clock();
	size_t begin2 = clock();
	for (size_t i = 0; i < 100000; i++)
	{
		TestFunc2(a);
	}
	size_t end2 = clock();
	cout << "(A):" << end1 - begin1 << endl;
	cout << "(A&):" << end2 - begin2 << endl;
}
int main()
{
	Test();
	return 0;
}

 clock会捕获当前程序运行的时间(单位为毫秒),创建了一个结构体,内部有一个大小为1000000的数组,传参时,若要创建出相应的形参,就要花费更多的时间,而引用作为参数,传过去的就是实参的引用,就略去了相应的形参的建造过程。
运行后效果如图
在这里插入图片描述
上边是作为参数,如果作为返回值呢?

using namespace std;
struct A
{
	int a[10000];
};
A a;//设置为全局变量
A TestFunc1() { return a; }
A& TestFunc2() { return a; }
void Test()
{
	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 << "(A):" << end1 - begin1 << endl;
	cout << "(A&):" << end2 - begin2 << endl;
}
int main()
{
	Test();
	return 0;
}

运行结果如图
在这里插入图片描述
 这里结构体中数组不要太大,形参太大有可能会爆栈,就会执行错误,所以这里将循环次数增使效果更加明显。
引用和指针的区别
 引用在语法概念上就是一个别名,没有独立的空间,和其引用实体共用一块区域。
在这里插入图片描述
然而,在底层实现上引用其实是按照指针的方式来实现的。
在这里插入图片描述
 汇编代码对比实现方式和指针一模一样,所以可以说C++引用就是按照指针方式实现的。

引用和指针的不同

  • 引用概念上给变量定义一个别名,指针存储一个变量的地址。
  • 引用在定义时必须初始化,指针没有要求。
  • 引用在初始化时引用一个实体后,就不能在引用其他实体,指针不同,指针只要不加const限定指针变量,就可以在任何时候指向任何实体。
  • 没有NULL引用,但有空(NULL)指针。
  • 在sizeof中含义不同,引用的结果为引用类型的大小,如果引用的变量是char类型,那结果就为1,但是指针变量始终都是4/8个字节。
  • 引用自加就是引用实体+1,指针自加,就是向后偏移一个类型的大小。
  • 有多级指针,但没有多级引用。
  • 访问实体方式不同,指针需要解引用,引用的话编译器自己会处理,可以直接使用。
  • 引用使用起来比指针相对安全。

内联函数

概念
 以inline修饰的函数叫做内联函数,编译时编译器会在调用该函数的地方将该函数展开,没有函数调用时建立栈帧的开销,提升程序的运行效率。
举一个Add的例子,在不展开的情况下,主函数通过调用该函数从而达到效果
在这里插入图片描述
 在Add函数前加上inline关键字将其修改成内联函数,在编译期间编译器会将函数体替换为函数的展开。
演示之前要更改一下编译器的默认设置,否则还是不会展开(dubug模式下,编译器默认不会对代码进行优化)下边是设置方式
在这里插入图片描述
打开属性后
在这里插入图片描述
在这里插入图片描述

加上inline再次转到反汇编进行查看,确实已经展开了。
在这里插入图片描述
特性

  • inline是一种以空间换时间的做法,如果编译器将函数作为内联函数处理,在编译期间就会用函数体替换函数调用。
  • 缺陷:会使目标文件变大,如果用很多内联函数,相当于程序要进行的步骤变多,本来的call变为函数体内部步骤。
  • 优势:少了函数栈帧调用开销,提高程序的运行效率。

inline对于编译器而言只是一个建议,不同编译器对inline的态度不同,一般建议当函数体很小时,并且不是递归且频繁调用的函数采用inline修饰,否则编译器会直接无视。
注意:
 inline不建议声明定义分离,因为inline被展开后,就没有函数地址可言了,链接就会找不到。
在这里插入图片描述
内联函数优点有很多,相比宏可以进行调试代码可读性好,可维护形也更强。
今天的内容到此结束,欢迎大家指导。
在这里插入图片描述

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

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

相关文章

【 云原生 | K8S 】kubeadm 部署Kubernetes集群

目录 1 环境准备 2 所有节点安装docker 3 所有节点安装kubeadm&#xff0c;kubelet和kubectl 4 部署K8S集群 4.1 查看初始化需要的镜像 4.2 初始化kubeadm 4.3 设定kubectl 4.4 所有节点部署网络插件flannel master&#xff08;2C/4G&#xff0c;cpu核心数要求大于2&am…

Stable Diffusion1.5网络结构-超详细原创

目录 1 Unet 1.1整体结构 2 VAE 3 CLIP 绘制软件&#xff1a;ProcessOn&#xff0c;以下图片保存可高清查看 1 Unet 1.1详细整体结构 1.2 缩小版整体结构 1.3 CrossAttnDownBlock2D 2 VAE 3 CLIP

elasticsearch+canal增量、全量同步

目录 一、搭建环境&#xff1a; 1.1 下载软件上传到linux目录/data/soft下 1.2 把所有软件解压到/data/es-cluster 二、单节点&#xff08;多节点同理&#xff09;集群部署elasticsearch 2.1 创建es用户 2.2 准备节点通讯证书 2.3 配置elasticsearch&#xff0c;编辑/d…

[模版总结] - 树的基本算法3 - 结构转化

二叉树结构转化 通常将二叉树根据某些要求进行结构重构&#xff0c;比如线性结构转化(链表&#xff0c;数组)&#xff0c;序列化等。 常见题型 注&#xff1a;这类题目最基本的解题思路是利用递归分治 (也可以使用迭代方法)&#xff0c;在构建树结构的时候&#xff0c;我们通…

餐厅订座预约小程序的效果如何

市场中无论哪种城市&#xff0c;餐厅非常多&#xff0c;一条不长的商业街&#xff0c;汇聚着数家餐饮品牌&#xff0c;且相互间竞争激烈&#xff0c;并且各个商家都希望用成本低高效率的方法引流及转化。 随着互联网深入各个行业&#xff0c;传统餐饮行业经营痛点不少。 传统餐…

c#正则表达式

using System.Text.RegularExpressions; namespace demo1 {/// <summary>/// 正则表达式&#xff08;Regular Expression&#xff09;是一种文本模式&#xff0c;包括普通字符&#xff08;例如&#xff0c;a&#xff5e;z的字母&#xff09;和特殊字符&#xff08;称为“…

【ArcGIS处理】行政区划与流域区划间转化

【ArcGIS处理】行政区划与流域区划间转化 引言数据准备1、行政区划数据2、流域区划数据 ArcGIS详细处理步骤Step1&#xff1a;统计行政区划下子流域面积1、创建批量处理模型2、添加批量裁剪处理3、添加计算面积 Step2&#xff1a;根据子流域面积占比均化得到各行政区固定值 参考…

Nginx反向代理与负载均衡与504错误

Nginx反向代理与负载均衡概念简介 关于代理 什么是代理 类似中介 在没有代理模式的情况下&#xff0c;客户端和Nginx服务端&#xff0c;都是客户端直接请求服务端&#xff0c;服务端直接响应客户端。 那么在互联网请求里面&#xff0c;客户端往往无法直接向服务端发起请求…

简单的 UDP 网络程序

文章目录&#xff1a; 简单的UDP网络程序服务端创建套接字服务端绑定启动服务器udp客户端本地测试INADDR_ANY 地址转换函数关于 inet_ntoa 简单的UDP网络程序 服务端创建套接字 我们将服务端封装为一个类&#xff0c;当定义一个服务器对象之后&#xff0c;需要立即进行初始化…

态路小课堂丨800G QSFP-DD OSFP VR8光模块简介

TARLUZ态路 近年来&#xff0c;随着IDC数据中心的不断升级&#xff0c;我们可以看到大多数企业已经在不断推出 800G系列光模块。其中&#xff0c;800G QSFP-DD/OSFP VR8&#xff08;以下简称800G VR8&#xff09;采用8通道全双工收发模块&#xff0c;能够满足短距离数据中心和云…

腾讯云服务器可用区是什么意思?可用区选择方法

腾讯云服务器可用区是什么意思&#xff1f;云服务器可用区如何选择&#xff1f;可用区是指在同一个地域内电力和网络相互独立的区域&#xff0c;可用区可以做到故障隔离&#xff0c;所以可用区存在的意义在于构建高可用、高容灾应用&#xff0c;将应用部署在不同可用区内&#…

VB.net WebBrowser网页元素抓取分析方法

在用WebBrowser编程实现网页操作自动化时&#xff0c;常要分析网页Html&#xff0c;例如网页在加载数据时&#xff0c;常会显示“系统处理中&#xff0c;请稍候..”&#xff0c;我们需要在数据加载完成后才能继续下一步操作&#xff0c;如何抓取这个信息的网页html元素变化&…

SpringJDBC模板类JdbcTemplate

Spring JdbcTemplate使用JdbcTemplate完成增删改查环境准备新增修改删除查询一个对象批量添加批量修改和批量删除使用德鲁伊连接池&#xff08;之前数据源是用我们自己写的&#xff09; JdbcTemplate JdbcTemplate是Spring提供的一个JDBC模板类&#xff0c;是对JDBC的封装&…

c语言-浅谈指针(2)

文章目录 1.数组名的理解2.使用指针访问数组3.一维数组传参的本质4.二级指针5.指针数组 本篇文章是关于数组与指针的&#xff0c;在上一篇指针内容的基础上进一步了解指针 1.数组名的理解 我们先来了解一个知识点&#xff1a;在给指针变量赋值时&#xff0c;数组用数组名赋给指…

光伏仪器-1763卫星帆板电源阵列模拟器

01 1763卫星帆板电源阵列模拟器 产品综述&#xff1a; 1763卫星帆板电源阵列模拟器用于解决卫星电源系统研制等帆板电源阵列及二次供电设备的测量和分析&#xff0c;解决电源分系统功能验证、现场试验等无法使用真实的帆板电源等带来的难题&#xff0c;用于卫星或卫星测试系…

顺序理清linux下的环境变量

文章目录 关于环境变量概念&#xff08;了解&#xff09;例引 环境变量 查看环境变量的方法echo && printenv 命令 环境变量的配置.bash_profile 常见 环境变量通过程序获取环境变量本地变量环境变量表 关于环境变量 概念&#xff08;了解&#xff09; 环境变量的概念…

有什么进销存软件,比较适合零售行业日常开单要求及库存记录?

本文将为大家总结一下对于进销存软件要求&#xff1a; 基础功能&#xff1a;可以日常开单、退换货处理、出入库进阶功能&#xff1a;电脑、手机数据同步&#xff0c;保障数据安全&#xff0c;可进行数据分析 其实无论是小型创业公司&#xff0c;还是一家大型企业&#xff0c;…

为什么SSL证书会有序列号

SSL证书中的序列号是为了唯一标识该证书。他是用于识别和跟踪证书的唯一标识符。以确保每个证书都具有唯一的值。 有序列号的原因如下&#xff1a; 唯一性&#xff1a;通过序列号&#xff0c;可以确保每个ssl证书都有一个独特的标识符。这对于区分不同的证书非常重要。 跟踪和…

tsconfig.json无法写入文件“XXXX“因为它会覆盖输入文件

在开发ts项目的时候&#xff0c;包错提示无法写入文件&#xff1a; tsconfig.json无法写入文件"XXXX"因为它会覆盖输入文件 这是tsconfig.json文件配置问题&#xff0c;需要加入下面的配置就好了&#xff1a; {"compilerOptions": {"outDir": …

教育案例分享 | 安全狗云安全体系为高校提升立体化纵深防御能力

一、客户情况 某高校有服务器500台&#xff0c;对外站点200个&#xff0c;核心交换流量20G。 二、客户痛点 校园网系统分类较多&#xff0c;并且每类网站中安全级重要程度又各不相同&#xff0c;同时有多个网络出口(如&#xff1a;教育网、电信网、移动网等)&#xff0c;二级学…