目录
1.函数重载
默认参数:能够使用不同数目的参数调用同一个函数;
函数多态(函数重载):能够使用多个同名的函数;
对于如何确定使用的重载函数版本就需要根据自己的经验和上下文的意义来判断了。
函数重载的关键是函数的参数列表----也称为函数特征标(function signature)。如果两个函数的参数数目和类型都相同,同时参数的排列顺序也相同,则它们的特征标相同,而变量名是无关紧要的。
c++允许定义名称相同的函数,但是他们的特征标要不同,即参数数目和/或参数类型要不同。
例如,可以看到下述参数类型不同,即特征表不同,虽然都是printf函数,但是却不是相同的函数。
void printf(cosnt char * str, int width);
void printf(double d, int width);
void printf(long l, int width);
在调用的时候,编译器就会根据所采用的用法使用具有相应特征标的原型;简而理解就是根据你传递的参数和个数来区分你要调用的是哪一个函数;下述分别对应上述的三个原型。
printf(“pancakes”, 15);
printf(1999.0, 10);
printf(1999L, 15);
使用被重载的函数时,需要使用正确的参数类型。
如果不正确的话,会发生什么呢?例如;
unsigned int year = 3210;
printf(year, 6);
假如只有一个函数原型,例如只有上面的第2种,很显然会发生类型强制转换;但是现在有三种函数原型,且第二种和第三种都可以,这又会怎么执行呢?此时会给编译器整懵逼,编译器就会报错。哈哈哈哈哈哈!!
---------------------------------------------------------分隔线---------------------------------------------------------------
下述这种虽然特征标不同,但是也不能共存。
double cube(double x);
double cube(double & x);
初始看起来是没什么影响的,但是举例说明,
cube(x);
请问对于上述两个cube()定义,哪一个是符合要求的?很显然两个都是符合的,所以对于引用和本身可以说是相同的特征标。
下面举个例子;
double gam(int n, float m);
long gam(int n, float m);
请问,上述声明合法吗?答案是不合法,初学者可能不会特意去关注这一点:特征标和函数返回类型,对于函数重载,返回类型是可以不同,但是特征标是必须要不同。很诚实的说明,我在看到这个例子的时候认为是不同的。
2.重载引用参数
不同引用类型的重载很有用。首先看下述三个函数原型;
void sink(double & r1);
void sank(const double & r2);
void sunk(double && r3);
左值引用参数r1与可修改的左值参数(如double变量)匹配;
const左值引用参数r2与可修改的左值参数、const左值参数和右值参数(如两个double值的和)匹配;
右值引用参数r3与左值匹配;
注意:与r1和r3匹配的参数都与r2匹配,那么如果重载使用这三种参数的函数,结果将如何?答案是将调用最匹配的版本。
这里可以去了解一下左值和右值是什么?
---------------------------------------------------------分隔线---------------------------------------------------------------
3.重载示例
下述是代码链接;
程序清单8.10;函数重载示例; · b4a6077 · Kite/C和C++ - Gitee.com
4.何时使用函数重载
(1)、仅当函数的基本功能比较相近,但是需要使用不同形式的参数实现功能时才应该使用函数重载,尽量不要用同一函数名去实现完全不相干的功能;
(2)、在同一个作用范围内使用函数重载,同一个范围即:同一个命名空间或者同一个类等;
(3)、重载函数的名称必须相同,函数的参数列表须不相同,即参数列表中参数的类型,参数的个数或参数的顺序不相同;
(4)、重载函数可以有相同的返回值类型或者不同的返回值类型,反之仅仅是返回类型不同不足以作为函数的重载。
5.什么是名称修饰
我们知道c编译器对于重名函数是没办法区分的,是肯定会报错的;那么c++是如何跟踪每一个重载函数呢?那就是因为这个神奇操作----名称修饰(name decoration)或名称矫正(name mangling),它根据函数原型中指定的形参类型对每个函数名进行加密。
举个简答的例子;
//未经名称修饰的函数原型
long function(int, float);
//经名称修饰加密后
?function@@YAXH
加密过后,转换为了内部表示方法,添加的符号随函数特征标而异,而修饰时使用的约定随编译器而异。