C++学习笔记17——函数重载

来源:互联网 发布:mac上怎么用office 编辑:程序博客网 时间:2024/05/16 13:54

1,重载函数概述

出现在相同作用域中的两个函数,名字相同而形参表不同。
注意:
(1)重载函数必须位于相同的作用域,局部作用域中声明的函数 (谁会这么做?!)会屏蔽全局作用域中的重名函数;
(2)必须是形参表不同,而不能仅仅是返回类型不同。如果形参表完全相同,而返回类型不同,则第二个声明是错误的;
(3)可以基于成员函数是否为const而重载,const类只能调用const成员函数,非const类优先调用非const成员函数;
(3)形参表是否相同要看本质而不能只看形式,如下例:
// 1,参数名会被忽略,所以形参表相同Record lookup(const Account &acct);Record lookup(const Account&); // parameter names are ignored// 2,编译时遇到Telno会被替换成Phone,导致两者形参表相同typedef Phone Telno;Record lookup(const Phone&);Record lookup(const Telno&); // Telno and Phone are the same type// 3,默认实参并不改变形参的个数,形参表相同Record lookup(const Phone&, const Name&);Record lookup(const Phone&, const Name& = "");// 4,对于非引用或指针类型的形参,const限定符被忽略,形参表相同Record lookup(Phone);Record lookup(const Phone);

2,函数匹配

函数匹配,又名重载确定,是将函数调用与重载函数集合中的一个函数相关联的过程。

2.1 函数匹配结果的3种结果

(1)编译器找到与实参最佳匹配(best match)的函数,OK;
(2)实参与重载函数集合中任何一个函数的形参都无法匹配,哪怕是在隐式类型转化之后,报错;
(3)存在多个与实参匹配的函数,但没有一个是明显的最佳选择,则此调用有二义性(ambiguous),报错;

2.2 函数匹配的步骤

(1) 候选函数
与被调用函数重名,且在调用点上其声明可见

(2)选择可行函数(viable function)
可行函数需要满足两点:
a. 形参个数与该调用的实参个数相同,但要注意默认实参的情况,默认实参也是实参;
b. 实参的类型必须与形参的类型匹配,或者可被隐式转化为对应形参的类型
关于类型匹配,分为两种情况:
a. 精确匹配
b. 实参类型经过隐式转换后匹配

(3)寻找最佳匹配(如果有的话)
原则:实参类型与形参类型越接近越好

(4)含有多个形参时的重载确认
如果有且仅有一个函数满足下列条件,则匹配成功
a. 每个实参的匹配都不劣于其他可行函数需要的匹配;
b. 至少有一个实参的匹配,优于其他可行函数提供的匹配;
如果找不到最佳匹配函数,则该调用有二义性错误

2.3 实参类型转换

确定最佳匹配所需的转换等级:
1. 精确匹配
2. 类型提升
3. 标准转换 
4. 类类型转换

比如下面的代码:
void ff(int);void ff(short);ff('a'); // char promotes to int, so matches f(int)
实参'a'被提升为int型,与ff(int)匹配

关于整型提升,提一句:
/*******************************************************************///               整型提升/*******************************************************************/char a = 1;char b = 2;char c = 0;c = a + b;// 虽然类型相同,但是a和b都被提升为int型再进行加法运算// 所以a+b占4个字节,// 然后赋值给c,发生隐式类型转换,变为char型,只占1个字节cout << "sizeof(c) = " << sizeof(c) << endl; // 1cout << "sizeof(a+b) = " << sizeof(a + b) << endl; // 4printf("c = %d\n",c);//c = 3
运行结果:


注意:没有哪个标准转换比其他标准转换具有更高的优先级
extern void manip(long);extern void manip(float);manip(3.14); // error: ambiguous call

所以double转 long int 和double 转float的优先级是一样的。该调用有二义性。



0 0
原创粉丝点击