C++ · 入门 · 03 | 函数重载

news2025/1/11 2:27:22

在这里插入图片描述
啊我摔倒了..有没有人扶我起来学习....


目录

  • 前言
  • 函数重载
    • 1.1 函数重载概念
    • 1.2 函数重载的意义
    • 1.3 C++支持函数重载的原理--名字修饰(name Mangling)
    • 1.4 返回值不同能否构成函数重载?


前言

  • 自然语言中,一个词可以有多重含义,人们可以通过上下文来判断该词真实的含义,即该词被重
    载了

函数重载

1.1 函数重载概念

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

  • 让我们依次看看这三种情况的示例:

  1. 参数类型不同
#include<iostream>
using namespace std;
int Add(int left, int right) 
{
	cout << "int Add(int left, int right)" << endl;
	return left + right;
}
double Add(double left, double right) 
{
	cout << "double Add(double left, double right)" << endl;
	return left + right;
}

int main()
{
	Add(10, 20);
	Add(10.1, 20.2);

	return 0;
}

可以看到是没有问题的在这里插入图片描述

  1. 参数个数不同
#include<iostream>
using namespace std;
void f()
{
	cout << "f()" << endl;
}
void f(int a)
{
	cout << "f(int a)" << endl;
}

int main()
{
	f();
	f(10);

	return 0;
}

可以看到是没有问题的在这里插入图片描述
3. 参数类型顺序不同

#include<iostream>
using namespace std;
void f(int a, char b) 
{
	cout << "f(int a,char b)" << endl;
}
void f(char b, int a) 
{
	cout << "f(char b, int a)" << endl;
}
int main()
{
	f(10, 'a');
	f('a', 10);

	return 0;
}

可以看到是没有问题的在这里插入图片描述

  • 需要注意
    • 所谓参数类型顺序不同,首先参数的类型不能一样,比如void f(int a, int b)void f(int b, int a)的参数类型顺序就是相同的!
    • 我们可以这么理解,这些变量所用的字母本质上都是一样的,就一个名字而已,所以int aint b是一个意思,所以不存在顺序问题
    • 所以可以确定,所谓顺序不同归根结底还是类型不同

1.2 函数重载的意义

  • 有了函数重载,那么就可以干很多方便的事了!

回顾一下以前C语言的实现:

int add(int x, int y)
{
	return x + y;
}
  • 只能计算整型?那我要计算浮点型呢,那不得多搞几个求和函数,而且名字还不能统一,这不是坑人吗~

有了函数重载以后~求和之路横着走:

#include<iostream>
using namespace std;
int add(int x, int y)
{
	return x + y;
}

double add(double x, double y)
{
	return x + y;
}

int main()
{
	cout << add(1, 2) << endl;
	cout << add(1.1, 2.2) << endl;

	return 0;
}

来看看结果:在这里插入图片描述

  • 而且,铁汁们有没有想起来,为何cout可以自动识别类型?好家伙,底层逻辑不就是函数重载吗!具体实现我们以后再谈谈

1.3 C++支持函数重载的原理–名字修饰(name Mangling)

  • 为什么C++支持函数重载,而C语言不支持函数重载呢?
  • C/C++中,一个程序要运行起来,需要经历以下几个阶段:预处理、编译、汇编、链接
    在这里插入图片描述
  1. 实际项目通常是由多个头文件和多个源文件构成,而通过C语言阶段学习的编译链接,我们
    可以知道,【假如当前a.cpp中调用了b.cpp中定义的Add函数时】,在编译后而链接前的中间阶段,a.o的目标文件中没有Add的函数地址,因为Add是在b.cpp中定义的,所以Add的地址在b.o中,那么怎么办呢?

  2. 所以链接阶段就是专门处理这种问题,链接器看到a.o调用Add,但是没有Add的地址,就
    会到b.o的符号表中找Add的地址,然后链接到一起

  3. 那么链接时,面对Add函数,链接接器会使用哪个名字去找呢(此时a.ob.o中都有)?这里每个C++编译器都有自己的函数名修饰规则

  4. 由于Windowsvs的修饰规则过于复杂,而Linuxg++的修饰规则简单易懂,下面我们使
    用了g++演示了这个修饰后的名字

  5. 通过下面我们可以看出gcc的函数修饰后名字不变。而g++的函数修饰后变成【_Z+函数长度
    +函数名+类型首字母】

    • 采用C语言编译器编译后结果
      在这里插入图片描述
      结论:linux下,采用gcc编译完成后,函数名字的修饰没有发生改变
    • 采用C++编译器编译后结果
      在这里插入图片描述
      结论:linux下,采用g++编译完成后,函数名字的修饰发生改变,编译器将函数参
      数类型信息添加到修改后的名字中
  6. 通过这里就理解了C语言没办法支持重载,因为同名函数没办法区分。而C++是通过函数修
    饰规则来区分,只要参数不同,修饰出来的名字就不一样,就支持了重载

1.4 返回值不同能否构成函数重载?

  1. 之前有个面试官问过一个同学这样的问题
    • 面试官:你觉得如果两个函数的函数名和参数是一样的,但是返回值不同,能不能构成函数重载?
    • 同学:不可以,因为函数名和参数都相同,导致命名修饰方式是一样的
    • 面试官:既然你觉得函数重载是因为命名修饰,从而可以区分出参数不同,那我把返回值也纳入命名修饰里,不也一样可以使得修饰名不同从而区分开来吗?
    • 同学:呃…
  2. 其实,按道理来说确实如面试官所言,我们只需要把“不同”,修饰到函数名里,就可以区分开两者了。但是!重点并不在这!

我们先来观察以下函数调用:

#include<iostream>
using namespace std;
void f()
{
	cout << "f()" << endl;
}

void f(int a = 0, char b = 1)
{
	cout << "f(int a,char b)" << endl;
}

int main()
{
	f(10);
	f(10, 20);

	f(); // 歧义  二义性

	return 0;
}
  • 在这里按照语法是构成函数重载的,而且f(10);f(10, 20);可以调用成功
  • 但是f();就会出现歧义。因为调哪个都可以,但你要调哪个呢。。。。存在歧义
  • 所以哪怕按照语法,构成了函数重载,也会受到调用的限制

再来观察以下函数调用

#include<iostream>
using namespace std;
int f(int a, int b)
{
	return 0;
}

char f(int a, int b)
{
    return 0;
}

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

	return 0;
}

结果是重定义!!在这里插入图片描述

  • 返回值不同,不构成重载原因,并不是函数名修饰规则。真正原因是调用时的二义性,无法区分,调用时不指定返回值类型
  • 其实按照语法来说就不涉及返回值的讨论,因为压根没法调用
  • 学到这里!想必铁汁们已经非常非常通透啦!!

在这里插入图片描述

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

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

相关文章

小米 2021 秋招面试总结

岗位:嵌入式软件工程师(相机驱动岗) 面试时间: 40 分钟 薪资: 28w+ 面试过程 面试官上来先来了一段他自己的自我介绍,流程还是比较规范的。 1、请进行一个简单的自我介绍(2分钟) 2、C语言全局变量可否定义在头文件中? 回答:不能,并且这不是一个好的习惯。 3…

【自学C++】C++输出cout

C输出cout C输出cout教程 在 C 语言 中我们需要输出一个 变量&#xff0c;可以使用 printf。printf 函数 在输出时&#xff0c;我们必须要指定输出的数据类型对应的格式化符&#xff0c;挺不方便。 在 C 中&#xff0c;我们要输出变量&#xff0c;直接使用 std 命名空间中的…

国科大抢课避坑+选课指南+教务系统操作

博客园&#xff1a; https://www.cnblogs.com/phoenixash/p/13669461.html 9月12日12&#xff1a;30&#xff0c;本菜鸡终于经历了国科大传说中的抢课大战&#xff0c;虽然自己之前准备的较多&#xff0c;但还是在抢课的时候掉进了不少坑里&#xff0c;趁现在还记忆犹新&#x…

【pandas】教程:10-文本数据的操作

Pandas 文本数据的操作 本节使用的数据为 data/titanic.csv&#xff0c;链接为 pandas案例和教程所使用的数据-机器学习文档类资源-CSDN文库 读入数据 import pandas as pd titanic pd.read_csv("data/titanic.csv")PassengerId Survived Pclass \ 0 …

指针进阶(2)

Tips 1. 2. 3. 碰到地址就等价于指针变量&#xff0c;里面存放着该地址的指针变量 4. 数组指针是存放数组的地址&#xff0c;指向的是一个数组&#xff1b;函数指针存放的是函数的地址&#xff0c;指向的是一个函数。 5. 地址就是指针&#xff0c;地址就是指针 6. 数…

LeetCode 138. 复制带随机指针的链表(C++)

思路&#xff1a; 用哈希表实现&#xff0c;创建一个哈希表来对应原链表中的每一个节点&#xff0c;这样也可以将原链表中的所有结点的next和random关系映射到哈希表复制链表中。 原题链接&#xff1a;https://leetcode.cn/problems/copy-list-with-random-pointer/description…

1658. 将 x 减到 0 的最小操作数

解法一&#xff1a;双指针 首先&#xff0c;每次操作可以移除数组 nums 最左边或最右边的元素&#xff0c;那么相当于求出l和rl和rl和r使得[0,l][r,n−1][0, l][r,n-1][0,l][r,n−1]之间所有元素之和等于xxx,并且元素个数最少。我们可以通过双重循环枚举l和r变量l和r变量l和r变…

马哥架构第1周课程作业

马哥架构第1周课程作业一. 画图解释一次web请求的过程。涉及tcp/ip, dns, nginx&#xff0c;wsgi。二. 编译安装nginx, 详细解读常用参数。三. 基于nginx完成动静分离部署 lamp。php到后端php-fpm, static/ 在nginx本地。3.1 配置 nginx 实现反向代理的动静分离3.2 准备后端 ht…

equals和==的区别

目录 1.基本数据类型和引用数据类型的说明 2. 3.equals 1.基本数据类型和引用数据类型的说明 基本数据类型&#xff1a;byte&#xff0c;short&#xff0c;int&#xff0c;long&#xff0c;float&#xff0c;double&#xff0c;char&#xff0c;boolean。 对应的默认值&…

2-4进程管理-死锁

文章目录一.死锁的概念二.死锁的处理策略1.死锁预防&#xff1a;破坏必要条件&#xff0c;让死锁无法发生2.避免死锁&#xff1a;在动态分配资源的过程中&#xff0c;用一些算法防止系统进入不安全状态&#xff08;1&#xff09;银行家算法&#xff08;2&#xff09;系统安全状…

Java if else分支结构精讲

Java 支持两种选择语句&#xff1a;if 语句和 switch 语句。其中 if 语句使用布尔表达式或布尔值作为分支条件来进行分支控制&#xff0c;而 switch 语句则用于对多个整型值进行匹配&#xff0c;从而实现分支控制。这些语句允许你只有在程序运行时才能知道其状态的情况下&#…

2022:不恋过往,不畏将来

一、开篇 少年有山海&#xff0c;踏过皆繁华。岁月不居&#xff0c;时节如流&#xff0c;时间在指尖悄悄流逝&#xff0c;人生即将翻开新的一年的篇章。2022年&#xff0c;注定是一个不平凡的年份&#xff0c;这一年&#xff0c;我们从关心世界到关心国家&#xff0c;最后关心自…

2023年12306购票平台自动化购票二|解决车次查找与预定

目录 一、说明 1.1、背景 1.2、说明 二、步骤 2.1、点击去购票 2.2、在搜索框中输入车次信息 2.3、点击查找 2.4、出现车次信息&#xff0c;进行筛选&#xff0c;如果有票则点击计入预定车票界面 三、结果 四、小节 一、说明 1.1、背景 接上文&#xff0c;春运抢不到…

适用于 Windows 的 5 大 PDF 编辑器

“如何在 Windows 7/8/10/11 上编辑 PDF 文件&#xff1f;” “适用于 Windows 7/8/10/11的最佳 PDF 编辑器是什么&#xff1f;” 升级到 Windows 7/8/10/11 后&#xff0c;你会发现很多应用程序在新的 Windows 系统上无法运行&#xff0c;包括 PDF 编辑器。然而&#xff0c;一…

POJ 3070 Fibonacci

Time Limit: 1000MSMemory Limit: 65536KTotal Submissions: 30932Accepted: 20284 Description In the Fibonacci integer sequence, F0 0, F1 1, and Fn Fn − 1 Fn − 2 for n ≥ 2. For example, the first ten terms of the Fibonacci sequence are: 0, 1, 1, 2, 3,…

opencv源码之中值滤波medianBlur_SortNet解读

背景中值滤波&#xff0c;最大值滤波&#xff0c;最小值滤波属于排序滤波&#xff0c;常用于图像去噪处理。最大/小值滤波的处理比较好理解&#xff0c;就是逐个比较窗口内的每个数字&#xff0c;每次比较会根据所属任务保留最大值&#xff0c;或最小值。假设滑动窗口是3*3&…

固体物理分子模拟实验(二)MPI的安装

固体物理分子模拟实验&#xff08;二&#xff09;MPI的安装 文章目录固体物理分子模拟实验&#xff08;二&#xff09;MPI的安装前言一、MPI是什么&#xff1f;二、安装步骤&#xff08;Ubuntu22.04mpich-4.0.2&#xff09;1、下载mpich解压包2、安装前置组件3、文件配置&#…

【一文讲通】如何检测数据满足同分布

1 统计指标的方法1.1群体稳定性指标&#xff08;Population Stability Index&#xff0c;PSI&#xff09;群体稳定性指标&#xff08;Population Stability Index&#xff0c;PSI&#xff09;&#xff0c; 衡量未来的样本&#xff08;如测试集&#xff09;及训练样本评分的分布…

【Linux】基础开发工具使用 --- vim

目录 前言 vim的基本概念 具体操作 插入模式 命令模式下的指令 底行模式下的指令 vim的配置 前言 &#x1f367;了解了 Linux 的一些基本的指令之后若要在 Linux 上进行程序的编写&#xff0c;除了 nano 以外&#xff0c;我们还可以选择 vim 进行编写。而 vim 是 vi 升级…

OJ万题详解––孤独的照片(C++详解)

题目 题目描述 Farmer John 最近购入了 N 头新的奶牛()&#xff0c;每头奶牛的品种是更赛牛&#xff08;Guernsey&#xff09;或荷斯坦牛&#xff08;Holstein&#xff09;之一。 奶牛目前排成一排&#xff0c;Farmer John 想要为每个连续不少于三头奶牛的序列拍摄一张照片。 然…