栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

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

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

文章目录
  • 1.什么是调用约定?
  • 2.对于c语言的调用约定
  • 3.对于c++的调用约定
  • 4.原因

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

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)这个情况,那么就会出现二义性,这样的话编译器就不知道调用那个了,所以说返回值不能构成函数重载的条件。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/847682.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号