C++函数重载

函数重载

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

要注意的是:只有函数名相同,形参不同(个数\类型\类型顺序不同)才能构成函数重载
而函数名相同,返回值不同的函数不构成函数重载

返回值类型与函数是否重载无关

  • 参数类型不同
int add(int a, int b)
{
	cout << "int:" << a + b << endl;
	return a + b;
}

double add(double a, double b)
{
	cout << "double:" << a + b << endl;
	return a + b;
}



int main()
{
	add(1,1);
	add(1.1,2.2);
}
  • 参数个数不同
void fun(int a)
{
	cout << a << endl;
}

void fcun(int a, int b)
{
	cout << a <<" "<< b << endl;
}

int main()
{
	fun(1);
	fun(1,2);
}
  • 参数类型顺序不同

这里注意:是参数类型顺序不同,而不是参数名顺序不同
int f(int a,double b)int f(int b,double a)是不构成重载的

void ff(int a, char b)
{
	cout << a << " " << b << endl;

}

void ff(char a, int b)
{
	cout << a << " " << b << endl;

}

int main()
{
	ff(10,'a');
	ff('a',10);
}

以上三个情况就是各种类型的函数重载

其实还有一种情况,就是当重载和缺省在一起时:

void fff()
{
	cout << 1 << endl;
}

void fff(int a = 0)
{
	cout << a << endl;
}

上面2个函数都可以通过编译
当我们使用实参对缺省参数赋值fff(1),可以正常运行
但是无参调用时会出现歧义,会报错
fff(),编译器不知道是要调用无参的那么函数还是调用缺省参数函数,发生冲突,无法运行


函数重载是怎样实现的

C语言不支持函数重载,而C++却能支持,C++是如何支持的呢?

这其实是在编译链接过程中,利用函数名修饰规则实现的

我们先来看一下编译链接的过程,如果我们在test.h中声明了函数,在test.cpp中实现,在_test.cpp文件中调用
实验代码如下:

test.h

#include <iostream>
using namespace std;

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

test.cpp

#include "test.h"

int add(int a, int b)
{
	return a + b;
}

double add(double a, double b)
{
	return a + b;
}

_test.cpp

#include "test.h"

int main()
{
	add(1,1);
	add(1.1, 2.2);
	return 0;
}

编译链接过程如下图:
在这里插入图片描述

调用函数都会被转换成call+一个地址,这个地址就是函数的地址
在这里插入图片描述

所以,这段代码在编译过程中,需要call2次,本来call需要去找到函数的地址,但是函数的定义在test.cpp文件中,地址也在test.i文件中,当前还未链接,所以还找不到地址
在这里插入图片描述
下面接着编译链接,在链接时,会生成一个符号表,这里面有函数名和其地址,这时2个文件是链接在一起的了
,之后就会进行找函数地址操作

但是C语言中,规定的是通过函数名进行寻址,因为这里有2个姓名相同的函数名,所以找不到正确的地址
所以C语言才不支持函数重载

下面,我们也通过linux系统,给;能够更方便得观察到函数名修饰规则

我们先在linux环境下创建一个c语言文件test.c
在这里插入图片描述
然后我们通过下面这些操作可以看到这个代码的汇编代码:
在这里插入图片描述
从汇编代码中找到调用func函数的部分:
在这里插入图片描述

这也证实了C语言是通过函数名进行寻址的

下面我们看一下C++是什么样的

先写一个cpp文件
在这里插入图片描述
然后还是观察它的汇编代码
可以看见汇编代码中,2个func的名字变了,这里不是func
在这里插入图片描述

这其实就是函数名修饰规则

第一个调用的函数名是_Z4funci
-Z是编译器规定的长度
4是指函数名func的长度
func就是原函数命
最重要的就是i,它jiusint类型的缩写
同理,第二个函数名最后的id就是intdouble类型的缩写

这里也能看出来为什么饭返回值不同不会构成函数重载?
因为返回值不会进入到函数名修饰规则里
参数会进入函数名修饰规则里,参数不同,最后函数名也不同

所以到这里就理解了为什么C++支持函数重载了


最后我们思考一个问题

如果我们把函数名修饰规则修改,允许返回值的类型以某种方式进入规则中,那么返回值不会是否会导致函数重载?

答案是也不可以

因为如果遇到如下的代码,2个函数的函数名相同,没有参数或参数都相同,只有返回值不同

int a()
{
	printf("int\n");
}

double a()
{
	printf("double\n");
}

int main()
{
	a();
	return 0;
}

这样到了汇编阶段,调用函数时返回值类型是体现不出来的,所以编译器也不知道到底是调用哪个函数
所以不论怎样,返回值类型不同不会导致函数重载

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

疯癫了的狗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值