聊聊 C# 方法重载的底层玩法

打印 上一主题 下一主题

主题 617|帖子 617|积分 1851

最近在看 C++ 的方法重载,我就在想 C# 中的重载底层是怎么玩的,很多朋友应该知道 C 是不支持重载的,比如下面的代码就会报错。
  1. #include <stdio.h>
  2. int say() {
  3.         return 1;
  4. }
  5. int say(int i) {
  6.         return i;
  7. }
  8. int main()
  9. {
  10.         say(10);
  11.         return 0;
  12. }
复制代码

从错误信息看,它说 say 方法已经存在了,尴尬。。。
一:为什么 C 不支持

要想寻找答案,需要了解一点点底层知识,那就是编译器在编译 C 方法时会将 函数名 作为符号添加到 符号表 中,这个 符号表 就是 call 到 say方法字节码  中间的一个载体,画个图大概就是这样。

简而言之,call 先跳转到 符号表, 然后再 jmp 到 say 方法,问题就出现在这里,符号表是一种类字典结构,是不可以出现 符号 相同的情况。对了,在 windbg 中我们可以用 x 命令去搜索这些符号,
为了论证我的说法,可以在汇编层面给大家验证下,修改代码如下:
  1. #include <stdio.h>
  2. int say(int i) {
  3.         return i;
  4. }
  5. int main()
  6. {
  7.         say(10);
  8.         return 0;
  9. }
复制代码
接下来再看下汇编。
  1. --------------- say(10) -----------
  2. 00C41771  push        0Ah  
  3. 00C41773  call        _say (0C412ADh)  
  4. --------------- 符号表 -----------
  5. 00C412AD  jmp         say (0C417B0h)  
  6. --------------- say body -----------
  7. 00C417B0  push        ebp  
  8. 00C417B1  mov         ebp,esp  
  9. 00C417B3  sub         esp,0C0h  
  10. 00C417B9  push        ebx  
  11. 00C417BA  push        esi  
  12. 00C417BB  push        edi  
  13. 00C417BC  mov         edi,ebp  
  14. 00C417BE  xor         ecx,ecx  
  15. 00C417C0  mov         eax,0CCCCCCCCh  
  16. 00C417C5  rep stos    dword ptr es:[edi]  
  17. 00C417C7  mov         ecx,offset _2440747F_ConsoleApplication6@c (0C4C008h)  
  18. ...
复制代码
知道了原理后,我们再看看 C++ 是如何在 符号表 上实现唯一性突破。
二:C++ 符号表突破

为了方便讲述,我们先上一段 C++ 方法重载的代码。
[code]using namespace std;class Person{public:        void sayhello(int i) {                cout

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

慢吞云雾缓吐愁

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表