初识C++(2)---C++入门之函数重载

本文详细介绍了C++中的函数重载,包括其定义、构成重载的条件(参数个数、类型、顺序不同),并解析了函数重载的原理,特别是C++如何通过函数名修饰来解决重名函数的调用问题。同时,强调了返回值不同不能构成重载的原因。最后,总结了函数重载的关键点,帮助读者深入理解这一核心概念。
摘要由CSDN通过智能技术生成


什么是函数重载

函数重载是函数的一种特殊情况,这是C++支持的一种功能,

在C语言中,如果函数出现重名,这时编译的话编译器是会报错的,但是C++支持函数的重载。

C++允许在同一作用域中声明几个功能类似的同名函数,常用来处理功能类似,但是数据类型不同的问题。


构成函数重载的条件

函数的重载类型有三种,满足这三种条件之一就可以构成函数的重载。

函数参数个数不同

//函数参数个数不同
void Print(int x)
{
	cout << x << endl;
}
void Print()
{
	cout << "hello world" << endl;
}

函数参数类型不同

//函数参数类型不同
void Print(int x)
{
	cout << x << endl;
}
void Print(double x)
{
	cout << x << endl;
}

函数参数顺序不同

//函数参数顺序不同
void Print(int x,double y)
{
	cout << x << endl;
	cout << y << endl;
}
void Print(double y,int x)
{
	cout << y << endl;
	cout << x << endl;
}

可以构成函数重载的只有这三种情况,或者同时满足这三种情况中的几种。

比如有的同学可能会问返回值不同能不能构成重载,答案是不可以的。

函数调用的时候是不能区分返回值的。还有缺省值不同,也不能构成重载

//不构成重载
void Print(int x)//没有缺省
{
	cout << x << endl;
}
void Print(int x = 10)//缺省
{
	cout << x << endl;
}

谈到了缺省值,这里有一个点需要注意,这里的场景下,虽然可以构成重载,但是也会出现问题。

在这里插入图片描述


函数重载原理

我们了解了函数构成重载的条件之后,不免会有疑问,

为什么C语言不支持函数重载,但是C++却可以支持呢?

下面来分析一下函数重载的原理

要想比较清晰的了解函数重载的原理,我们就要先回顾一下

编译器编译程序的过程,以及每个过程进行的工作

预处理编译汇编链接
头文件展开、宏替换、条件编译、去掉注释检查语法、生成语法树、词义分析、符号汇总生成汇编代码 等汇编代码转换成二进制机器码 ,生成符号表合并段表、符号表的合并和符号表的重定位
.i文件.s文件.o文件.out文件

编译的每一个过程都会产生对应的文件,不同的编译器会有一些差别,

上面列举的是Linux环境下编译过程中产生的对应的文件。

我们知道,在C语言中如果函数重名,编译器报错的信息显示函数已有主体,

根据编译的过程,函数是链接过程出现问题。

void test()
{
	printf("hehe\n");
}
int main()
{
	test();
	return 0;
}

调试一下这段代码,看一下汇编代码

在这里插入图片描述
调用test函数的时候,会有一条call指令,然后根据给出的地址,会跳转到函数执行的指令行。

函数编译的时候,在编译到函数时,如果是函数的声明,这时是不会给出地址的,

如果当前文件有函数的定义,那么编译时就会给出地址,这样编译器就可以根据地址调用函数了。

到这里我们就知道了,编译器是根据函数名+地址来进行调用的,

C语言在编译时对函数名的处理就是简单的使用给定的函数名,

所以导致在编译链接的过程中,造成歧义,对于相同函数名的函数,不知道调用哪一个,

所以C语言是不支持函数重载的。那么C++是怎么支持的呢?

C++的目标文件不是直接简单的用函数名来标识和查找函数。

C++引入了函数名修饰规则,但是这个函数名修饰规则在不同的编译器下面是不一样的。

有了函数名修饰规则,所以只要参数不同

汇编的时候产生的符号表中的函数就不存在二义性和冲突了。

链接的时候,main函数去调用两个重载函数,查找地址时,就非常明确了。

这里举一个函数名修饰规则的例子

Linux环境下,g++的编译器函数名修饰规则

_Z + 函数名长度 + 函数名 + 函数参数类型首字母

比如这个函数

void test(int x = 10)
{
	cout << x << endl;
}

编译后生成的函数名修饰为

_Z4testi


总结

到这里我们就明白了为什么C语言不支持函数重载,因为同名函数没有办法区分。

而C++是通过函数名修饰规则来区分,只要函数的参数满足构成重载的三个条件,

修饰出来的名字就会不一样,就可以支持重载了。

还有,上面之所以用g++编译器来举例是因为windows环境下,函数名修饰的规则很复杂,不利于理解。

所以,我们也明白了,函数重载是要求参数不同,而返回值不同不能构成重载,因为编译链接的时候与返回值没有关系。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值