C++ -函数重载-详解

news2024/11/20 2:23:43

博客主页:【夜泉_ly】
本文专栏:【C++】
欢迎点赞👍收藏⭐关注❤️

在这里插入图片描述

C++ -函数重载-详解

  • 1.是什么
  • 2.怎么用
    • 2.1示例
  • 3.原理
    • 3.1C/C++编译链接过程
    • 3.2函数名修饰规则
    • 3.3过程
      • 1.调用函数的过程
      • 2.编译阶段的函数调用
  • 总结

1.是什么

如果在百度中搜索重载这个词,会得到以下结果:
在这里插入图片描述

不怎么容易理解吧🤣。
其实,可以简单的把重载理解为同名,而函数重载就是定义同名函数
例如:

void Add(int a, int b);
void Add(double a, double b);

这在C语言中肯定会报错,但C++支持这样的操作,并且在调用时会根据传入的参数类型自动匹配对应的函数。

2.怎么用

函数重载不能支持所有同名函数,首先,参数列表需要不同,主要分三方面:

  • 参数个数不同
  • 参数类型不同
  • 类型顺序不同

这意味着,如果函数名相同、参数列表相同、但是返回值不同不构成重载!例如:

int func(int a, int b);
double func(int a, int b);

2.1示例

void func();	 //无参数
void func(int a);//单参数

构成重载——参数个数不同。


void func(int a, int b);//参数顺序不同
void func(int b, int a);//参数顺序不同

有歧义,不构成重载。
报错信息如下:
在这里插入图片描述


void func(int  a, int b);//第一个参数为整数
void func(char a,int b);//第一个参数为字符

构成重载——参数类型不同。


void func(int a, char b);//第一个参数为整数
void func(char a,int b);//第一个参数为字符

构成重载——类型顺序不同。


这时有人想到了缺省参数💡,于是出现了这种比较特殊的情况:

void func();
void func(int a = 0);

是否构成重载?
构成重载!符合重载函数的定义。
在这里插入图片描述
可以在上图的右下角看见,程序正常退出。

那么这样写有没有问题?
有问题!如果写出下面这句代码,则会引发歧义:

func();

在这里插入图片描述

3.原理

这里有两个问题:

  • 为什么C语言不支持重载,C++支持重载?
  • C++是怎么支持重载的?

想要解决这些问题,需要了解编译链接过程,以及函数名修饰规则

自动识别类型-函数重载。

3.1C/C++编译链接过程

这里只是简单提两句,因为更详细的内容我也不知道:

  1. 预处理:
    头文件展开 / 宏替换 / 条件编译 / 去掉注释……(.h/.c/.cpp文件变为.i文件)

  2. 编译:
    检查语法 / 生成汇编代码(.i文件变为.s文件)

    上面那个缺省参数的特殊情况在编译时不会报错,就是因为语法没错。

  3. 汇编:
    将汇编代码转化为二进制的机器码(.s文件变为.o文件)

  4. 链接:
    生成符号表 / 将目标文件(.o–>object)链接成可执行程序(.exe/a.out

3.2函数名修饰规则

C++ 编译器在编译过程中会对函数名进行修饰,以便区分不同的重载函数。修饰规则通常包括以下内容:

  • 参数类型:函数参数的类型信息。
  • 参数数量:函数参数的数量。
  • 返回类型:函数的返回类型信息。

在不同环境下,函数名修饰规则也不同,但目的都是将同名变为不同名。

3.3过程

二进制机器码与汇编代码是相互转换的关系,也就是说,如果想查看程序的底层实现,可以通过查看汇编代码来获取更直观的信息。
我在这里又建了三个文件:
func.h:

#pragma once
#include <stdio.h>
void func(int a, int b);
void func(double a, double b);

func.c:

#include "func.h"
void func(int a, int b)
{
	printf("void func(int a, int b)\n");
}
void func(double a, double b)
{
	printf("void func(double a, double b)\n");
}

test.c:

#include "func.h"
int main()
{
	func(1, 2);
	func(1.0, 2.0);
	return 0;
}

1.调用函数的过程

在开始调试的时候转到反汇编,会看见:
在这里插入图片描述
这里可以看见,在每个函数调用语句下都有一条“call指令+地址”:
在这里插入图片描述
这里重点关注第一个call指令,在调试到那里时,会跳转到jump指令,而这个jump指令的地址就是刚刚call指令后跟的地址:
在这里插入图片描述
而这个jump指令,会根据它后面跟的地址,真正跳转到函数的位置:
在这里插入图片描述

2.编译阶段的函数调用

在编译过程中,函数调用会被转化为 call 指令,后面跟着函数名(函数的地址),类似刚刚看见的:
在这里插入图片描述
当函数的定义和声明分离时,编译阶段无法立即获取函数的实际地址,因为此时只包含了(.h),即编译器只看到声明,而函数的定义在其他文件中。
在这种情况下,编译器能通过声明完成编译,但不会生成最终的地址。(我只会用VS2022,而且不知道怎么调出这种效果😅)
在链接阶段,链接器才会将调用语句与实际的函数定义关联起来,找到函数的真正地址。

编译错误与链接错误:

  • 因为编译器在看到声明时只知道函数存在,但没有具体的实现细节,因此只要声明正确,编译可以顺利通过。
  • 但是,链接阶段如果找不到函数的定义,就会发生链接错误。

当然,当函数的定义与声明在同一个源文件中时,编译器可以直接找到函数的地址,因为定义已经存在,编译器能够在编译阶段就处理地址问题。


回到函数重载:
编译阶段,C++编译器会通过函数名修饰为每个重载函数生成唯一的符号,从而确保编译器能够区分同名但参数列表不同的重载函数。
而C语言不会进行函数名修饰,因此遇到同名函数会编译失败。
这就解释了为什么C语言不支持重载,C++支持重载?和C++是怎么支持重载的?

总结

函数重载是 C++ 中一项重要的特性,它提高了代码的灵活性和可读性。
通过函数名修饰规则,C++ 在编译过程中实现了自动类型匹配,避免了调用时的歧义。
在实际编程中,合理使用函数重载可以极大地提高编程效率和代码质量。

在这里插入图片描述


希望本篇文章对你有所帮助!并激发你进一步探索编程的兴趣!
本人仅是个C语言初学者,如果你有任何疑问或建议,欢迎随时留言讨论!让我们一起学习,共同进步!

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

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

相关文章

Adobe Bridge简体中文版百度云下载与安装(附教程)

如大家所熟悉的&#xff0c;Adobe Bridge常常简称为BR&#xff0c;是一款数字资产管理软件&#xff0c;可以帮助用户浏览、组织、搜索和管理各种类型的媒体文件&#xff0c;如照片、音频、视频等。 Bridge发展至今有许多个版本&#xff0c;目前来说常用的版本有Bridge 2018、2…

2024东湖高新下半年水测公示名单啦

2024东湖高新下半年水测公示名单啦 公示时间9月13日-9月20日&#xff0c;快看看你过了没&#xff01;&#xff01; 东湖高新区报名水测共有2600多人&#xff0c;水测公示通过1201人&#xff0c;部分人员免考。 水测通过后就赶紧整理好申报材料&#xff0c;准备申报了&#xff…

2.1 HuggingFists系统架构(一)

系统架构 HuggingFists的前端主体开发语言为HtmlJavascript&#xff0c;后端的主体开发语言为Java。在算子部分有一定份额的Python代码&#xff0c;用于整合Python在数据处理方面强大能力。 功能架构 HuggingFists的功能架构如上&#xff0c;由下向上各层为&#xff1a; 数据存…

【程序大侠传】应用内存缓步攀升,告警如影随形

前序 在武侠编码的江湖中&#xff0c;内存泄漏犹如隐秘杀手&#xff0c;潜伏于应用程序的各个角落&#xff0c;悄无声息地吞噬着系统资源。若不及时发现和解决&#xff0c;必将导致内存枯竭&#xff0c;应用崩溃。 背景&#xff1a;内存泄漏的由来 内存泄漏&#xff0c;乃程序…

TensorRT-LLM保姆级教程(三)-使用Triton推理服务框架部署模型

随着大模型的爆火&#xff0c;投入到生产环境的模型参数量规模也变得越来越大&#xff08;从数十亿参数到千亿参数规模&#xff09;&#xff0c;从而导致大模型的推理成本急剧增加。因此&#xff0c;市面上也出现了很多的推理框架&#xff0c;用于降低模型推理延迟以及提升模型…

redis哨兵启动出现 +sdown master mymaster 192.168.x.x

场景&#xff1a; 搭建好哨兵之后&#xff0c;哨兵一启动&#xff0c;过了30秒就会判断master sdown&#xff0c;但是检查配置是没有问题。 日志&#xff1a; Redis-master启动日志&#xff1a;没看到任何异常&#xff0c;所以master无异常 Redis-哨兵启动日志&#xff1a; …

深度学习技术概览

一、深度学习技术概览 深度学习&#xff0c;作为机器学习的一个分支&#xff0c;其核心在于通过构建多层神经网络模型来模拟人脑的学习过程。与传统的机器学习算法相比&#xff0c;深度学习能够自动从原始数据中提取高级抽象特征&#xff0c;而无需人工进行复杂的特征工程。这…

Java项目实战II基于Java+Spring Boot+MySQL的网上摄影工作室(源码+数据库+文档)

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者 一、前言 在数字化时代&#xff0c;摄影艺术已不再局限于传统媒介&#xff0c;而是借助互联网平台绽放新的光彩…

基于遗传优化算法的多AGV栅格地图路径规划matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 4.1 栅格地图表示 4.2 路径编码 4.3 目标函数 5.完整程序 1.程序功能描述 基于遗传优化算法的多AGV栅格地图路径规划matlab仿真&#xff0c;分别测试单个AGC的路径规划和多个AGV的路径规划…

虹科技术分享 | CAN XL总线测试与译码

CAN XL是第三代控制器局域网协议&#xff0c;建立在经典CAN和CAN FD网络的基础上&#xff0c;并支持向后兼容。它面向车载网络&#xff0c;使用单个差模总线连接多个控制器和传感器。由于高度的耐用性和对布线需求最小的总线拓扑结构&#xff0c;控制器局域网协议越来越多地进入…

虚拟社交的新时代:探索Facebook的元宇宙愿景

随着技术的不断进步&#xff0c;社交媒体的形态也在悄然变化。Facebook&#xff08;现名Meta&#xff09;正站在这一变革的前沿&#xff0c;积极探索元宇宙的愿景。元宇宙不仅是虚拟现实&#xff08;VR&#xff09;和增强现实&#xff08;AR&#xff09;的结合&#xff0c;更是…

Spring Boot房屋租赁系统:技术架构解析

2 关键技术简介 2.1 JAVA技术 Java是一种多用途并且强大的编程语言&#xff0c;可用于开发运行在移动设备、台式计算机以及服务器端的软件。Java已及其流行。Java只要编写一次&#xff0c;无论什么地方都可以运行启动[1]。 Java语言是应用很广泛的语言&#xff0c;用它编写出的…

【JVM原理】运行时数据区(内存结构)

JVM &#xff08;Java Virtual Machine&#xff09;原理 文章目录 四、运行时数据区&#xff08;内存结构&#xff09;4-1 线程私有区域程序计数器&#xff08;program counter Register&#xff09;本地方法栈&#xff08;Native Method Stacks&#xff09;Java 虚拟机栈&…

Python办公自动化教程(004):PDF添加水印

1.4 PDF文档水印添加 【1】安装库 pip install reportlab pip install PyPDF2【2】代码 import iofrom PyPDF2 import PdfWriter, PdfReader from reportlab.lib import pagesizes # 页面样式 from reportlab.lib.units import cm from reportlab.pdfbase import pdfmetric…

【Verilog学习日常】—牛客网刷题—Verilog企业真题—VL68

同步FIFO 描述 请设计带有空满信号的同步FIFO&#xff0c;FIFO的深度和宽度可配置。双口RAM的参考代码和接口信号已给出&#xff0c;请在答案中添加并例化此部分代码。 电路的接口如下图所示。端口说明如下表。 接口电路图如下&#xff1a; 双口RAM端口说明&#xff1a; 端口…

828华为云征文|使用Flexus X实例集成ES搜索引擎

目录 一、应用场景 1.1 Flexus X实例概述 1.2 ES搜索引擎 二、安装相关服务 2.1 安装Elasticsearch7.17.0 2.2 安装kibana7.17.0 三、开通安全组规则 四、整体感受 4.1 Flexus X实例 4.2 使用感觉 一、应用场景 1.1 Flexus X实例概述 Flexus X实例是华为云推出的一款…

Windows内核编程基础(2)

上下文环境 应用层应用程序工作在用户模式&#xff0c;内核驱动程序工作在内核模式。这里的用户模式和内核模式是基于CPU的特权环来定义的&#xff0c;CPU提供了0环~3环(ring 0 ~ ring 3)共四个特权环&#xff0c;Windows操作系统使用了其中的0环和3环&#xff0c;0环为内核模…

【深度学习】(7)--保存最优模型

文章目录 保存最优模型一、两种保存方法1. 保存模型参数2. 保存完整模型 二、迭代模型 总结 保存最优模型 我们在迭代模型训练时&#xff0c;随着次数初始的增多&#xff0c;模型的准确率会逐渐的上升&#xff0c;但是同时也随着迭代次数越来越多&#xff0c;由于模型会开始学…

大数据-148 Apache Kudu 从 Flink 下沉数据到 Kudu

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

Spring Boot房屋租赁平台:现代化解决方案

1 绪论 1.1 研究背景 中国的科技的不断进步&#xff0c;计算机发展也慢慢的越来越成熟&#xff0c;人们对计算机也是越来越更加的依赖&#xff0c;科研、教育慢慢用于计算机进行管理。从第一台计算机的产生&#xff0c;到现在计算机已经发展到我们无法想象。给我们的生活改变很…