上篇C++57个入门知识点_12 函数重载及其条件(函数重载:同一作用域中有多个同名函数、条件:(1)函数名相同(2)参数个数不同、类型不同、顺序不同(3)返回值和调用约定不考虑(4)作用域相同)本篇介绍函数重载的调用规则和本质。
简单总结就是:编译器会按照匹配程度来决定调用哪个函数,最匹配的优先调用,而经过名称粉碎之后,其实重载函数是不一样的
。
总结放于前:
1. 函数重载的调用规则(三步走):
1.1 根据函数名找对应的函数,作为候选函数
- 如果候选函数个数为0,则报未定义错误(找不到标识符)
1.2 候选函数个数>0,从候选中找到匹配的函数(完全匹配,不完全匹配-可以转换的匹配(char<->int, float<->double, float<->int
))
- 如果匹配的函数个数==0,则错误(隐式转换失败)
- 如果匹配的函数个数>0,找到最佳匹配。
1.3 最佳匹配个数=1,就会调用该函数;最佳匹配的个数>1,就会报二义性
2.函数重载的本质: C++编译器通过名称粉碎确定函数的不同
1.函数重载的调用规则实例
1.1 正常的函数重载实例
有以下代码,在main中我们调用两个同名函数,但是其参数选择不同的类型:
#include <iostream>
float getMax(int a, float b) {
return ((a) > (b)) ? (a) : (b);
}
char* getMax(char* a, char* b) {
return ((a) > (b)) ? (a) : (b);
}
int main(int argc, char* argv[])
{
char* p = nullptr;
char* q = nullptr;
char* n = getMax(p, q);
int m = getMax(1, 2.0f);
return 0;
}
运行结果:main中会根据参数调用对应的函数
1.2存在隐式转换的函数重载
如果对上面的代码进行修改,将main函数中的函数调用改为: int m = getMax(1.0f, 2);
这个时候会怎么调用呢?答案是依然调用的是float getMax(int a, float b) {}
,这是因为数字是很难转换为char*,除非采用强转的方式,而int
和float
是可以相互隐式转换
的。
如果当程序中出现完全符合参数类型的函数时,肯定选择完全符合的情况
float getMax(float a, int b) {
return ((a) > (b)) ? (a) : (b);
}
1.3 参数均有部分符合的函数重载
如果函数有如下情况:两个函数参数均有部分符合调用的数据
float getMax(float a, int b) {
return ((a) > (b)) ? (a) : (b);
}
float getMax(int a, float b) {
return ((a) > (b)) ? (a) : (b);
}
int main(int argc, char* argv[])
{
int m = getMax(1.0f, 2.0f);
return 0;
}
编译结果:显示具有二意性。
2.函数重载的本质
C++编译器通过名称粉碎确定函数的不同
,本系列的namespace_11
有介绍如何去查看.obj
中对应的源码。
C语言中是不支持名称粉碎的,因此不支持函数重载。
.obj中的内容:
3. 学习视频地址:C++57个入门知识点_13 函数重载调用规则及本质