🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
## 一.概述 1. **重载** 在不同类型上做类似运算而又用相同名字的情况称为重载。 2. **重载解析** C++用一种函数命名技术可以准确判断应该调用哪个重载函数。 3. **重载依据** 返回类型、形参类型、形参个数、形参次序。 >[danger] 注意 > >1. 返回类型不能作为单独重载解析的依据。 >2. 不能用typedef定义的类型名来区分重载函数声明中的参数。 4. **匹配顺序(简版)** 类型完全一致 -> 自动类型转换 -> 用户定义的转换。 ```c++ //若有函数原型 void fun(int); void fun(double); //调用函数 fun(1); //匹配void fun(int); fun(1.0); //匹配void fun(double); fun('a'); //匹配void fun(int); fun(3.14f); //匹配void fun(double); ``` ## [$]二.实参匹配顺序 1. 精确匹配: + 类型完全相同。 + 左值到右值的转换。 + 数组转换成指针以及函数转换成函数指针。 2. 向参数添加 `const` 限定符或者从实参中删除 `const` 限定符。 3. **常量转换** 指向变量的指针或引用转换成指向常量的指针或引用。 4. **类型提升** 整型提升和浮点提升。 5. **其他的算术转换、指针转换、布尔转换** 等隐式转换。 6. 用户定义的转换 ## [$]三.函数重载与域 >[info]重载函数集合中的全部函数都应在同一个域中声明。 1. 一个声明为局部的函数将隐藏而不是重载一个全局域中声明的函数。 ```c++ void print(const char*); void print(double d); int MyFunc() { void print(int i); print("Hello World");//错了!void print(const char*);声明被隐藏了 return 0; } ``` 2. 两个不同类的成员函数不能相互重载,为不同名字空间成员的函数不能相互重载。 3. 用 `using` 关键字声明函数时会把所有的重载函数引入作用域。 4. 用 `using` 关键字引入一个同名的函数时,相当于重载了这个同名函数。 >[danger]如果 `using` 声明向一个域中引入了一个函数,而该域中已经有同名函数且具有相同的参数表,则该 using 声明就是错误的。 ```c++ namespace demo { void print(const char*); void print(double); void print(int); } void print(int,int); using demo::print; int MyFunc() { print(2020);//OK,demo::print(int) print(2020,2019);//OK,print(int,int) return 0; } ``` ## [$]四.函数重载解析 ```c++ //演示代码 void print(const char* string); void print(double d); void print(int i); void print(int i,int j); int main() { print(2020);//<-探讨该语句的解析过程 return 0; } ``` 1. 确定函数调用考虑的重载函数的集合,确定函数调用中实参表的属性。 >`void print(const char* string);` >`void print(double d);` >`void print(int i);` >`void print(int i,int j);` 2. 从重载函数集合中选择函数,该函数可以在(给出实参个数和类型的)情况下用调用中指定的实参进行调用。 + **可行函数** 选出来的函数。 + **参数够** 可行函数的参数个数与调用的实参表中的参数数目相同,或者可行函数的参数个数多一些,但是每个多出来的参数都要有默认值。 + **可转换** 对于每个可行函数,调用中的实参与该函数的对应的参数类型之间必须可以进行隐式类型转换。 + **无匹配情况** 没有函数与调用匹配。这个调用就是错的。 >`void print(int i);` **可行** **精确匹配** >`void print(double d);` **可行** **转换后匹配** 3. 选择与调用最匹配的函数。 + 从实参类型到相应可行函数参数所用的转换都被划分等级。 + **最佳匹配函数** 在实参的转换上不能比别的同名函数差,而且某些实参的转换要比别的同名函数好。 >`void print(int i);` **最佳匹配函数√** 精确匹配优于转换后匹配 >如果还没找到,那么你调用的东西是二义的。