共计 2448 个字符,预计需要花费 7 分钟才能阅读完成。
一、根本定义
重载,顾名思义从字面上了解就是反复装载,打一个不失当的比如,你能够用一个篮子装蔬菜,也能够装水果或者其它,应用的是同一个篮子,然而能够用篮子反复装载的货色不一样。
函数重载是 C ++ 多态(动态多态)的特色体现,它能够容许重复使用同一个函数名(篮子)的函数,然而函数的参数列表(篮子装的货色)是能够不一样的。这样就能够利用函数的重载功能设计一系列性能相近,然而性能细节不一样的函数接口。
二、利用举例
以同一个函数 printData 为例:
#include <iostream>
using namespace std;
void printData(const char *str, int num)
{// 函数体;}
void printData(const char *str)
{// 函数体;}
void printData(double data, int num)
{// 函数体;}
void printData(int data, int num)
{// 函数体;}
void printData(long data, char num)
{// 函数体;}
class Test
{
public:
void MyPrint(int num) {cout << "class int:" << num << endl;}
void MyPrint(float num) {cout << "class float:" << num << endl;}
void MyPrint(char num) {cout << "class char:" << num << endl;}
};
int main(void)
{printData("hello", 5); // (const char *str, int num)
printData("hello"); // (const char *str)
printData(1993.0, 97);
printData(1993, 98);
printData(1993L, 99);
Test test1;
test1.MyPrint(2); // class int: 2
test1.MyPrint(2.0f); // class float: 2.0 浮点型必须要显式类型,否则编译器不晓得该转换为 int 还是 float。test1.MyPrint("hello"); // class char: hello
return 0;
}
应用重载函数时,须要在函数调用中应用与对应的重载函数匹配的函数参数类型。
而如下:
unsigned int para = 4321;
printData(4321, 5);
此时的 printData 调用和哪个原型匹配呢?答案它不与任何函数原型匹配,而没有匹配的原型不会进行调用其中某一个函数,C++ 会尝试用规范的强制类型转换与之匹配,比方应用 printData(double data, int num),就能够将 para 的类型强制转换为 double 类型。然而还有 printData(int data, int num) 和 printData(long data, char num) 这两个函数能够强制转换 para。因而,C++ 将回绝这种函数的调用,将这种调用视为谬误。
重载函数通常用在同一个作用域内,用同一个函数名命名一组性能类似的函数,这样做缩小了函数名的数量,进步了函数的通用性,防止了名字空间的净化,对于程序的可读性有很大的益处。
三、非函数重载的状况
上面这种两种状况不能视为函数重载:
int fun(int a);
int fun(int &a);
从编译器的角度登程,参数 a 与参数列表原型 int a 和 int &a 都匹配,编译器无奈确定应用哪个函数,为防止这种凌乱,编译器在查看参数类型时将把类型自身和类型援用看作是同一个特色类型。
int fun(int a, float b);
double fun(int a, float b);
C++ 不容许这样的形式重载函数,尽管返回值能够不一样,然而参数列表必须不一样。
四、函数重载的应用准则
(1)、仅当函数的基本功能比拟相近,然而须要应用不同模式的参数实现性能时才应该应用函数重载,尽量不要用同一函数名去实现齐全不相干的性能;
(2)、在同一个作用范畴内应用函数重载,同一个范畴即:同一个命名空间或者同一个类等;
(3)、重载函数的名称必须雷同,函数的参数列表须不雷同,即参数列表中参数的类型,参数的个数或参数的程序不雷同;
(4)、重载函数能够有雷同的返回值类型或者不同的返回值类型,反之仅仅是返回类型不同不足以作为函数的重载。
五、FAQ
1、C++ 中对函数重载是如何解决的?
在.cpp 文件中,尽管两个函数的函数名一样,然而,C++ 编译器在外部应用“名称润饰”或“名称改正”转换,它依据函数中参数列表的区别为每个函数进行加密,例如:
int fun(int a, float b) 和 double fun(int a, float b)
编译器在外部能够转换为:
?fun@@YAHHH@Z 和?fun@@YAMMM@Z
”?” 示意名称开始,”?” 后边是函数名;“@@YA”示意参数表开始,后边的 3 个字符别离示意返回值类型,两个参数类型;“@Z”示意名称完结。
因为在.cpp 文件中,两个函数生成的符号表中字符的名称不一样,所以是能够编译通过的。
2、C 语言中为什么不能反对函数重载?
编译器在编译.c 文件时,只会给函数进行简略的重命名。具体的办法是给函数名之前加上 ”_”;所以编译前两个函数名雷同的函数在编译之后的函数名也照样雷同;因而调用时会因为不晓得到底调用哪个而出错。
int fun(int a, float b) 和 double fun(int a, float b)
编译器在外部都转换为:_fun,无奈辨别,
只有不同的函数名字 int fun1(int a, float b) 和 double fun2(int a, float b)
编译器在外部转换为:_fun1 和_fun2,这能力辨别开来。
更多技术内容和书籍材料获取敬请关注公众号“明解嵌入式”