C++函数重载.docx
《C++函数重载.docx》由会员分享,可在线阅读,更多相关《C++函数重载.docx(16页珍藏版)》请在三一办公上搜索。
1、C+函数重载本资料由-大学生创业|创业|创业网 每个现象后面都隐藏一个本质,关键在于我们是否去挖掘 写在前面: 函数重载的重要性不言而明,但是你知道C+中函数重载是如何实现的呢?这个可以分解为下面两个问题 1、声明/定义重载函数时,是如何解决命名冲突的? 2、当我们调用一个重载的函数时,又是如何去解析的? 这两个问题是任何支持函数重载的语言都必须要解决的问题!带着这两个问题,我们开始本文的探讨。本文的主要内容如下: 1、例子引入 o 什么是函数重载? o 为什么需要函数重载? 2、编译器如何解决命名冲突的? o 函数重载为什么不考虑返回值类型 3、重载函数的调用匹配 o 模凌两可的情况 4、编
2、译器是如何解析重载函数调用的? o 根据函数名确定候选函数集 o 确定可用函数 o 确定最佳匹配函数 5、总结 1、例子引入 1.1、什么是函数重载? 函数重载是指在同一作用域内,可以有一组具有相同函数名,不同参数列表的函数,这组函数被称为重载函数。重载函数通常用来命名一组功能相似的函数,这样做减少了函数名的数量,避免了名字空间的污染,对于程序的可读性有很大的好处。 When two or more different declarations are specified for a single name in the same scope, that name is said to ove
3、rloaded. By extension, two declarations in the same scope that declare the same name but with different types are called overloaded declarations. Only function declarations can be overloaded; object and type declarations cannot be overloaded. 摘自ANSI C+ Standard. P290 在线代理|网页代理|代理网页| 减肥药排行榜|淘宝最好的减肥药|
4、什么减肥药效果最好|减肥瘦身药| 本资料由-大学生创业|创业|创业网 看下面的一个例子,来体会一下:实现一个打印函数,既可以打印int型、也可以打印字符串型。在C+中,我们可以这样做: 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. #include using namespace std; void print(int i) coutprint a integer :iendl; void print(string str) coutprint a string :strlog.txt反汇编并将结果重定向到
5、log.txt文件中,然后分析log.txt文件。 发现函数void print(int i) 编译之后为: 发现函数void print(string str) 编译之后为: 在线代理|网页代理|代理网页| 减肥药排行榜|淘宝最好的减肥药|什么减肥药效果最好|减肥瘦身药| 本资料由-大学生创业|创业|创业网 我们可以发现编译之后,重载函数的名字变了不再都是print!这样不存在命名冲突的问题了,但又有新的问题了变名机制是怎样的,即如何将一个重载函数的签名映射到一个新的标识?我的第一反应是:函数名+参数列表,因为函数重载取决于参数的类型、个数,而跟返回类型无关。但看下面的映射关系: void
6、print(int i) - _Z5printi void print(string str) - _Z5printSs 进一步猜想,前面的Z5表示返回值类型,print函数名,i表示整型int,Ss表示字符串string,即映射为返回类型+函数名+参数列表。最后在main函数中就是通过_Z5printi、_Z5printSs来调用对应的函数的: 80489bc: e8 73 ff ff ff call 8048934 80489f0: e8 7a ff ff ff call 804896f 我们再写几个重载函数来验证一下猜想,如: void print(long l) - _Z5printl
7、 void print(char str) - _Z5printc 可以发现大概是int-i,long-l,char-c,string-Ss.基本上都是用首字母代表,现在我们来现在一个函数的返回值类型是否真的对函数变名有影响,如: 1. #include 在线代理|网页代理|代理网页| 减肥药排行榜|淘宝最好的减肥药|什么减肥药效果最好|减肥瘦身药| 本资料由-大学生创业|创业|创业网 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. using namespace std; int max(int a,int b) ret
8、urn a=b?a:b; double max(double a,double b) return a=b?a:b; int main coutmax int is: max(1,3)endl; coutmax double is: max(1.2,1.3)endl; return 0; int max(int a,int b) 映射为_Z3maxii、double max(double a,double b) 映射为_Z3maxdd,这证实了我的猜想,Z后面的数字代码各种返回类型。更加详细的对应关系,如那个数字对应那个返回类型,哪个字符代表哪重参数类型,就不去具体研究了,因为这个东西跟编译器
9、有关,上面的研究都是基于g+编译器,如果用的是vs编译器的话,对应关系跟这个肯定不一样。但是规则是一样的:“返回类型+函数名+参数列表”。 既然返回类型也考虑到映射机制中,这样不同的返回类型映射之后的函数名肯定不一样了,但为什么不将函数返回类型考虑到函数重载中呢?这是为了保持解析操作符或函数调用时,独立于上下文,看下面的例子 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. float sqrt(float); double sqrt(double); void f(double da, float fla) float fl=sqrt(da);/调用sqrt(double
10、) double d=sqrt(da);/调用sqrt(double) fl=sqrt(fla);/调用sqrt(float) d=sqrt(fla);/调用sqrt(float) 如果返回类型考虑到函数重载中,这样将不可能再独立于上下文决定调用哪个函数。 在线代理|网页代理|代理网页| 减肥药排行榜|淘宝最好的减肥药|什么减肥药效果最好|减肥瘦身药| 本资料由-大学生创业|创业|创业网 至此似乎已经完全分析清楚了,但我们还漏了函数重载的重要限定作用域。上面我们介绍的函数重载都是全局函数,下面我们来看一下一个类中的函数重载,用类的对象调用print函数,并根据实参调用不同的函数: 1. 2.
11、3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. #include using namespace std; class test public: void print(int i) coutintendl; void print(char c) coutchar _ZN4test5printEi void print(char c) - _ZN4test5printEc 注意前面的N4test,我们可以很容易猜到应该表示作用域,N4可能为命名空间、test类名等等。这说明最准确的映射机制为:作用域+返回类
12、型+函数名+参数列表 3、重载函数的调用匹配 现在已经解决了重载函数命名冲突的问题,在定义完重载函数之后,用函数名调用的时候是如何去解析的?为了估计哪个重载函数最适合,需要依次按照下列规则来判断: 精确匹配:参数匹配而不做转换,或者只是做微不足道的转换,如数组名到指针、函数名到指向函数的指针、T到const T; 在线代理|网页代理|代理网页| 减肥药排行榜|淘宝最好的减肥药|什么减肥药效果最好|减肥瘦身药| 本资料由-大学生创业|创业|创业网 提升匹配:即整数提升,float到double 使用标准转换匹配:如int 到double、double到int、double到long double
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- C+ 函数 重载
链接地址:https://www.31ppt.com/p-3153749.html