IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++之函数重载 -> 正文阅读

[C++知识库]C++之函数重载

函数重载

函数重载构成条件

函数重载是C++允许在同一个作用域中声明几个名字相同功能相似的函数,函数重载常被用于处理功能类似、数据类型不同的问题。
高级语言在设计时就有一条原则,语言不能存在二义性,C++为了保证语言不存在二义性对函数重载进行约束:
要构成重载函数必须满足以下几个条件之一:

  1. 形参类型不同
  2. 形参个数不同
  3. 形参顺序不同

通过代码实现一个重载函数,以下代码位于三个文件:
test.cpp

#include"func.h"

int main()
{
	f(1, 1.1);

	return 0;
}

func.h

#include<stdio.h>
#include<stdlib.h>

void f(int a, float b);
void f(float a, int b);

func.cpp

#include"func.h"

void f(int a, float b)
{
	printf("f(int a, float b)\n");
}

void f(float a, int b)
{
	printf("f(float a, int b)\n");
}

以上函数构成重载。上面函数构成重载满足了函数形参顺序不同的规则。运行结果为:
image-20220102142053935

从程序运行结果来看,我们不需要指定函数来运行,程序本身根据所传实参类型来联系实际场景判断用哪个函数,这种方式极大的方便程序员。

无法构成重载的特例

值得注意的是,函数的返回类型不同是无法构成函数重载的如:

void f(int a, float b)
{
	printf("f(1)\n");
}

int f(int a, float b)
{
	printf("f(2)\n");
}

还有无法构成重载的特例:

void f(a = 1)
{
    printf("f(a = 1)\n");
}

void f()
{
    printf("f()\n");
}

上面这种情况若是调用时有实参,编译器可以判断为有形参的函数执行,若无实参调用f();,由于上面函数有缺省参数,编译器无法判断调用的是哪个函数,程序也就无法执行。
!!!注意 main函数无法重载!!!

不建议使用函数重载的场景

函数重载对于程序员使用起来确实方便,但在有些场景不建议使用函数重载。函数重载使用时最好应用于功能相似的函数。有些时候给函数起不同的名字有利于程序员理解函数的功能。举个例子以下为几个负责移动屏幕光标的函数:

void moveHome();
void moveAbs(int, int);
void moveRel(int, int, string direction);

将以上几个函数名字起为move固然也可以,但是这几个函数构成重载之后函数名就失去了本来拥有的信息:

void move();
void move(int, int);
void move(int, int, string direction);

显然第二个命名方式是不如第一个的。

C语言无法构成重载

在vs2019环境中将上面三个文件中的.cpp后缀全改为.c后缀,编译程序后程序报错

image-20220102162759548

由此可以看出C语言不支持函数重载。
那么为什么C语不支持函数重载而C++支持呢?

函数名字修饰

从代码到程序经过预处理,编译,汇编,链接几个过程,C++为了支持函数重载在编译阶段对函数名做了修饰,即名字修饰。由于Windows系统下名字修饰较为复杂,后面的名字修饰演示全为Linux系统下的演示。
在Linux系统下将test.cpp文件进行汇编后反汇编查看:

image-20220102173430008

image-20220102173534172

对比两个函数修饰过的名字和咨询大佬后知道Linux系统下函数名修饰规则:

_Z+函数名长度+函数名+形参类型
形参类型:
i int
f float
c char
pi *int
其它照此类推

由此可以看出,被以上的3个条件约束的函数重载时修饰后的名字是不会重复的,如此才能构成函数重载

C语言反汇编

我们可以通过此方法来看一下C语言的名字修饰情况,揭秘以下C语言为什么不知此重载。
将一个f函数注释掉后反汇编:

image-20220102192958741

可以看到,f函数是没有经过任何修饰的。所以每个f函数名字都是一样的,编译器无法区分函数,所以无法构成重载。
Windows下反汇编的函数名字不太好看,但还是可以通过一些方法看到。

image-20220102193921311

如上图,修饰过的函数名有些复杂,不利于分析,关于Windows下的函数名修饰规则可以在搜索引擎上看一下。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-01-03 15:53:52  更:2022-01-03 15:55:50 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 10:43:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码