重载函数:
针对不同的参数类型提供不同的操作,如果两个函数的名字相同,并且在相同的作用域中声明,但是参数表不同则它们是重载函数。重载函数的名字相同,但它们的参数表必须不同:或者参数个数不同,或者参数类型不同。返回类型不能区分两个重载函数,因为调用时可以忽略函数的返回值。
当一个函数名在某个作用域中多次声明时,编译器根据下面的规则判断这些函数是否重载:
(1)如果两个函数的参数表中参数的个数或类型不同,则这两个函数是重载的。
(2)如果两个函数的返回类型和参数表都精确匹配,则认为是同一函数的重复声明。
(3)如果两个函数的参数表相同,但返回类型不同,则认为是错误的重复声明。
(4)如果两个函数的参数表中,只有默认值参数不同,则认为是重复声明。
(5)参数类型是const或volatile时,对函数声明的识别并不影响。但是如果一个程序同时提供两个函数定义,而这两个定义中参数的区别只是const或volatile限定符时,会产生重复定义错误。如果const或volatile应用在指针或引用参数上,在判断函数声明是否相同时,需要考虑const和volatile修饰符。
重载函数解析:将函数调用与重载函数集合中的一个函数相关联的过程。
重载函数解析过程:实际上就是一组函数中选择最匹配的一个函数,这里进行匹配的是函数调用中实参的数目和类型与函数形参的数目和类型,其中可能应用到隐式转换:
重载函数解析的步骤如下:
(1)确定函数调用考虑的重载函数的集合,确定函数调用中实参表的属性;
(2)从重载函数集合中选择可以用指定实参调用的函数——可行函数;
(3)在可行函数中选择与调用最匹配的一个——最佳匹配函数;
为了选择最佳匹配函数,从实参到形参的类型转换被划分了不同的等级。最佳匹配函数满足两个条件:一,应用在实参上的转换不比调用其他可行函数所需的转换差;二,在某些实参上的转换比其他可行函数对该参数的转换好。
参数类型转换:
参数的类型转换被划分为几个等级,从最佳到最差依次为:
(1)精确匹配
Ø 实参与形参的类型精确匹配。
Ø 左值到右值的转换。
Ø 数组到指针的转换。
Ø 函数到指针的转换。
Ø 限定修饰符转换。
(2)标准提升
Ø Char、unsigned char 或short类型的实参被提升为int类型。
Ø Float类型的实参提升为double类型。
Ø 枚举类型实参被提升为下列第一能够表示其所有枚举常量的类型:int、unsigned int、long或者unsigned long.
Ø Bool类型的实参提升为int类型。
(3)标准转换
Ø 整值类型转换:从任何整值类型或枚举类型向其他整值类型转换(不包括标准提升)。
Ø 浮点转换:从任何浮点类型到其他浮点类型的转换(不包括标准提升)。
Ø 浮点-整值转换:从任何浮点类型到任何整值类型或从任何整值类型到任何浮点类型的转换。
Ø 指针转换:从整数0到指针的转换和任何类型的指针到void*的转换。
Ø Bool转换:任何整值类型、浮点类型、枚举类型或指针类型到bool类型的转换。
Ø 所有标准转换被视为等价的,类型之间的接近程度不被考虑,如char到unsigned char的转换并不比char 到double 的转换更优先。
Ø 如果有两个可行函数都要求对实参进行标准转换才能匹配各自的形参类型,则该调用是二义的,会引起编译错误。
(4)用户自定义转换:可以为自己的类类型定义类型转换操作。
(5)省略号参数:函数有省略号参数,可以与任何类型和个数的实参进行匹配。
(6)无匹配:无法应用以上任何一种转换,则无匹配的函数。
重载函数和缺省函数:
重载函数和缺省函数的根本区别在于:重载函数是根据实参的个数和类型在一组同名函数中选择一个来调用,而缺省参数的函数是以不同的形式调用同一个函数。