一,函数重载规则
调用重载函数的过程可以简单的称为重载解析
大致过程如下:
①创建候选函数列表,根据函数名称选择匹配的函数。其中包含与调用名称相同的函数和
模板函数
②使用候选函数列表创建可行函数列表,这些都是形参数目正确的函数,为此,会有一个
隐式的转换,比如float转换为double,long转换为double,而模板可以为double创建实例函数
③确定是否有最佳匹配,有,则使用它,否则编译报错。
对②的转换规则是:
(Ⅰ)完全匹配,但是常规函数优先于模板函数
(Ⅱ)提升转换,float转换成double,char转换称为int等,
(Ⅲ)标准转换,高精度往低精度转等
比如int变成char(高->低),long变成double
(Ⅳ)用户自定义的转换(后续更新。。。)
从实参 | 到形参 |
---|---|
T | T& |
T& | T |
T[] | *T |
T(argument_list) | T(*)(agument_list)//函数指针 |
T | const T |
T | volatile T |
T* | const T |
T* | volatile T* |
另外,有时候两个函数都完全匹配,这也可以完成重载解析,选出最佳函数,
这是const和非const的在指针和引用方面在函数重载方面的区别了
重点笔记👇
非const指针实参和非const 形参匹配,非const引用实参和非const形参匹配
但如果传入的参数是普通类型,既不是指针,也不是引用,那么就不存在const和非const的调用差别了
函数重载解析例子
引入《C++ Primer Plus》例子,P290页
/*#1*/void recyle(blot);
/*#2*/void recyle(const blot);
/*#3*/void recyle(blot&);
/*#4*/void recyle(const blot&);
struct blot{
int a;
char b[10];
}
blot ink={25,"sports"};
recyle(ink);
若只定义#1和#2则调用recyle会出现二义性,因为const和非const的区别只在指针和引用的上
普通类型是没有这个区别的
若只定义#3和#4,就会调用#3,因为非const引用实参和非const形参的精确匹配的,不需要到const引用的转换,因此调用#3