为什么c不可以重载,而c++可以重载?

让我先来介绍一下调用约定。

1.什么是调用约定?

一个函数从调用到完成都经历了哪些步骤呐?

1 .调用要使用的函数,把调用者的函数入栈

2 . 把函数的参数压栈或者存储到寄存器

3. 把函数使用到的一些寄存器压栈

4.执行函数

5.处理函数返回值

6.把那些压栈的寄存器的值恢复到原来的值

7.清空那些压栈参数把返回值传递给寄存器

8 返回到调用者函数

而函数的调用约定就是一个规定,规定怎样传参数,谁负责善后,以及修饰函数的名字。

__cdecl__stdcall__fastcall
参数传递方式栈传递,参数从右向左依次入栈栈传递,参数从右向左依次入栈寄存器和栈传递,函数的第一个参数和第二个参数(从左向右)<=32字节的参数,通过ecx和edx传递,如果有其他参数,则剩余参数从右向左依次传递
清理栈方式由调用者负责恢复栈顶指针由被调者负责恢复栈顶指针由被调者负责恢复栈顶指针
适用场合c/c++,MFC的默认方式Win API要求速度快

2.对于c语言的调用约定

这些是它常用来修饰名字的调用约定

__cdecl__stdcall__fastcall
__functionname__functionname@number@functionname@number

__cdel :在函数名前面直接加 __
__functionname@number : 在函数名前面加 __,后面跟 @ 参数的字节数
__fastcall : 在函数名前面加 __后面跟@参数字节数

比如说 void add(int a,char b)

依次用它们来修饰之后的结果
1. __add
2. __add@5
3. @add@5

3.对于c++的调用约定

它的修饰规则为

1.以?标识函数名的开始,后跟函数名

2.

2.1 :当为__cdecall调用约定时,函数名后面跟"@@YA"标识参数表开始
2.2 : 当为__stdcall调用约定,函数名后面跟"@@YG"标识参数表开始
2.3 :   当为__fastcall调用约定,函数名后面跟"@@YI"标识参数表开始

3.参数表的符号表示( 在下面

4.参数的第一项为该函数的返回类型,其后依次跟参数的数据类型,指针标识在其所指的数据类型前

5.参数表后以"@Z"标识整个名字的结束,如果没有参数,则以Z结束

参数表的符号

 X: void
 D : char
 E:unsigned char
 F:short
 H:int
 I:unsigned int
 j:long
 K: unsigned long
 M:float
 N:double
_N:bool
PA:表示指针,后面的代号表明指针类型,如果相同类型的指针连续出现,以"0"代替,一个0代表一个重复

比如是 void func(int * p1,int *p2,double * p3)

使用的是__cdecall调用约定,那么它的函数修饰名为

?func@@YAXPAH0PAN@Z

4.原因

知道了它们的修饰规则后,答案就显而易见了

对于c语言来说,一般情况下使用的是第一种调用约定,而这种调用约定,只是在函数名前面加了_

比如说有这么两个函数
void fun(int a,int b)
void fun(int a,char b)
无论是第一个函数,还是第二个函数,它们的函数名修饰之后,都会变成_fun,所以这样编译器根本无法区分你调用的是那个函数,所以无法重载

对于c++来说
它一般使用的是第一种调用约定
它可以根据函数的返回值,还有参数类型和个数,把函数名修饰成不同的字符串

void fun(int a,int b) ?func@@YAXHH@Z
void fun(int a,char b) ?func@@YAXHD@Z

所以c++可以根据函数不同的参数数量和类型构成重载

那这样的话,你会不会有一个问题,那就是,返回值不同的话,它的函数名经过修饰后明明不同呀,为什么返回值不同不能构成重载呐?

但是你想这样一个问题

在这里插入图片描述

就上面两个函数,当你使用fun(1.2)进行调用的时候,它俩有什么区别吗?
它俩都有两个参数,都是int 类型,所以说都符合(1,2)这个情况,那么就会出现二义性,这样的话编译器就不知道调用那个了,所以说返回值不能构成函数重载的条件。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值