IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 为什么c不可以重载,而c++可以重载? -> 正文阅读

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

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-29 11:55:13  更:2022-04-29 11:56:33 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/20 21:40:31-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码