函数重载机制的奥秘

转载 2016年05月31日 09:45:49


C++是怎么区分同名的函数呢?原来是编译器悄悄使用了一个称作名字分裂规则的机制。

现代民俗给女孩子起名喜欢‘娜’、‘薇’等字,一个班出现两个‘李娜’,不是什么新鲜事,然而老师居然也能应付。老师是怎么做的呢?老师把她们的名字进行了扩展,把能区分她们一些特性加到姓名里来了,于是乎,出现了‘大李娜’、‘小李娜’、‘胖李娜’、‘瘦李娜’。假如她们高矮、胖瘦都一样,老师也有办法,把她们的家长找来开会:“有劳诸位阁下,请立即给你们的宝贝女儿改名”。

以Borland C++编译器为例,它等于说把我们写的每一个函数名都用一个新名字代替了。这个新名字由下列几部分组成:

‘@’+类名+‘@’+函数名+“$q”+参数类型符1+参数类型符2+…

其中,‘+’号是拼接在一起的意思。

参数类型符是这样的:

       若无参数,则让它是字符‘v’(取void的字头);

       若此参数是int型,则让它是字符i’;

       若此参数是double型,则让它是字符d’,以此类推。

如下例所示:

       class  MyClass

       {   public:     :

              valueX(int);                //分裂为@MyClass@ valueX$qi

              valueX(int, int );           //分裂为@MyClass@ valueX$qii

              valueX(int,double);       //分裂为@MyClass@ valueX$qid

              valueX(double,int );      //分裂为@MyClass@ valueX$qdi

              valueX();                   //分裂为@MyClass@ valueX$qv

       }; 

 

函数声明和定义时的名字变了,调用时函数的名字当然也必须变才能正确匹配。调用时的名字分裂如下所示:

int  main()

{  MyClass  obj;

                  :

         obj. valueX(3);                    //分裂为@MyClass@ valueX$qi

         obj.valueX(3, 3);                         //分裂为@MyClass@ valueX$qii     

         obj.valueX(3.0, 3);                     //分裂为@MyClass@ valueX$qdi    

         obj.valueX( );                               //分裂为@MyClass@ valueX$qv     

         return0;

}

 

我们理所当然地感到,名字分裂这个词有点不恰当,似乎叫名字组合,或名字拼接才对。

至此,我们可以解开几个谜团:

①通过名字分裂以后,成员函数对编译系统来说就可以作为外部函数来处理,由此也可见C++是如何封装其成员函数的。如上例,如果我们在主函数里这样调用成员函数:valueX(3, 3),而不是obj.valueX(3,3),那么,它通过名字分裂之后是@ valueX$qii(3, 3),就不可能匹配到。

①    C++为什么强调函数的原型形式?试想一下,如果不把参数类型逐一列出,编译系统怎么进行名字分裂?函数调用还能够匹配得上吗?

②    C++规定,对于同名函数的参数,必须或者是个数不同,或者是参数类型的排列不同,或者二者皆不同。如果不如此规定,则分裂后的函数名相同。

我们看到,函数的返值类型并没有作为名字分裂的成分。也就是说,两个函数,如果除了返值类型不同之外,其余都相同,将会导致这两个函数进行名字分裂之后是一模一样的,这就出现了两意性(ambiguous),而计算机程序是绝不允许出现两意性的。

必须指出,名字分裂是在编译时进行的,而不是在运行时进行的。


  博客地址:http://blog.csdn.net/chenshuzhenteacher/article/details/8066810

虚函数和函数重载

函数重载: 面向对象编程过程中,针对定义大量的函数,函数命名难度开始出现,为了解决此问题,希望通过函数重名来达到简化编程的目的。 例如,要声明两个求绝对值的函数:int abs(i...
  • fenxinzi557
  • fenxinzi557
  • 2016年05月12日 11:44
  • 392

c++函数重载机制实现原理

一、c++函数重载的定义:在同一作用域类,一组函数的函数名相同,参数列表不同(参数个数不同/参数类型不同),返回值可同可不同二、函数重载的作用:重载函数通常用来在同一个作用域内命名一组功能相似的函数,...
  • gogogo_sky
  • gogogo_sky
  • 2017年05月30日 00:48
  • 360

《编码的奥秘》目录摘要及读书笔记

本文由Markdown语法编辑器编辑完成。渴望交流是大多数人的天性。在本书中,“编码”通常指一种在人和机器之间进行信息转换的系统。换句话说,编码即是交流。有时我们将编码看得很神秘,其实大多数编码并非都...
  • inter_peng
  • inter_peng
  • 2016年08月06日 01:17
  • 1164

《编码的奥秘》读后感

历经两周左右的时间,终于把《编码的奥秘》这本书看完了。不得不说,这真是一本好书,深入浅出的讲解了大量与计算机与编码有关的东西。十分推荐对计算机有兴趣的朋友看看这本书,无论有没有技术功底,是否专业人士,...
  • u012745215
  • u012745215
  • 2015年05月18日 00:29
  • 3067

关于《编程的奥秘》一书未说完的话

关于《编程的奥秘》一书未说完的话第一部分 写作缘由 2006年1月,在春节前的一星期,我从出版社终于拿到了样书,不久,在海淀图书城的科技书店中也看到了这本书,只不过被摆在一个很不显眼的角落,不知道有没...
  • bitfan
  • bitfan
  • 2006年01月25日 22:33
  • 10740

大学总结之影响我最深的十本书

今天是“世界读书日”,前几天微博上转发非常多的一条微博:“一日不读书,无人看得出;一周不读书,开始会爆粗;一月不读书,智商输给猪”,确实阅读是很重要的,对此我深有体会。大学四年我读了大量的书,其中大多...
  • hazir
  • hazir
  • 2012年04月23日 23:14
  • 3866

读《编码的奥秘》有感

来源见豆瓣:http://book.douban.com/review/1074474/           屈指算来,这几年看过不少计算机书籍,根据经济学中的边际效益递减原理,读书带来的知识的增加和...
  • jj12345jj198999
  • jj12345jj198999
  • 2011年07月23日 17:16
  • 1376

咨询的奥秘--笔记

咨询的奥秘--笔记        随着毕业入职新公司,做SCM的实施顾问,一方面在学习Oracle EBS的相关系统功能,另一方面了解开发相关的PL/SQL、Forms Builder等相关知识,还抽...
  • u012025054
  • u012025054
  • 2015年08月30日 00:35
  • 2033

《算法心得-高效算法的奥秘(原书第2版)》pdf

下载地址:网盘下载 内容简介  · · · · · · 【编辑推荐】 由在IBM工作50余年的资深计算机专家撰写,Amazon全五星评价,算法领域...
  • cf406061841
  • cf406061841
  • 2017年05月27日 19:06
  • 556

读Petzold-编码的奥秘-记录

1, 2,
  • tran119
  • tran119
  • 2017年11月27日 16:25
  • 51
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:函数重载机制的奥秘
举报原因:
原因补充:

(最多只允许输入30个字)