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

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; // 1
	cout << "sizeof(a+b) = " << sizeof(a + b) << endl; // 4
	printf("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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值