绑定:
确定对重载函数的哪个函数进行调用的过程称为绑定。
绑定的优先级次序:
1.精确匹配->2.对实参类型向高类型转换后的匹配->3.对实参类型向低类型以及相容类型转换后的匹配
例如:
int add(int x,int y)
{
return x + y;
}
int add(int x,double y)
{
return x + y;
}int add(double x ,double y)
{
return x + y;
}
int add(double x,int y){
retrun x + y;}
int add(int x,int y,int z)
{
return x + y + z;}
(1) add(5,6);
//实参类型为(int,int),通过精确匹配进行了函数绑定。
(2) add('A','A'+'0');
//实参类型为(char,int),不能从重载函数中获得精确匹配,于是(向高类型转换)将char型转换成int型,然后与add(int,int)绑定。
(3)add( float(8),float(9) );
//实参类型为(float,float),不能从重载函数中获得精确匹配,于是(向高类型转换)将float型转化为double型,然后与add(double,double)绑定。
(4)add(double(8),double(9),double(10));
//实参类型为(double,double,double),不能从重载函数中获得精确匹配,向高类型转换后也得不到匹配,于是(向低类型转换)将double型转化为int型,然后与add(int,int,int)绑定。
二义性:
(5)add(long double(8),9);
//实参类型为(long double,int),不能从重载函数中获得精确匹配,向高类型转换后也得不到匹配,于是(向低类型转换)。
由于存在add(int ,int)、add(double,int)两个重载函数,编译器不知道进行哪种类型的转换,与哪个函数绑定,这种现象叫做绑定(匹配)二义性。
消除二义性的办法:
1.添加重载函数定义,使调用获得精确匹配,例如增加定义add(long double, int)。
2.将函数的实参进行强制类型转换,使调用获得精确匹配。其调用形式可改为add(double( long double(8) ),9 ),但改为add(long double(8),long doble(9) )同样会出现绑定二义性(存在add(int ,int)、add(double,double)两个重载函数)。
注意:
1.函数重载的返回类型我们默认不能改变,但实际上是可以不相同的。只是如果仅仅只是返回类型不同,其他条件均一致时,此时会出现二义性。例如:
int add(int x,int y)
{
return x + y;
}double add(int x,int y)
{
return x + y;
}
此时,使用add(5,6)就会出现报错。
2.重载函数与带默认形参值的函数一起使用时,有可能引起二义性。例如:
int add(int x,int y)
{
return x + y;
}int add(int x,int y,int z = 0)
{
return x + y;
}
当调用add(8,9)时,不知与add(int,int)还是add(int,int,int = 0)绑定。
消除这种二义性的方法是增加或者减少实参个数。
3.函数形参中的占位参数情况特殊,例如:
两者不是重载函数关系
int add(int x,int y)
{
return x + y;
}int add(int x,int )
{
return x + y;
}
当调用add(8,9)时,两者情况均可以,但编译器会认为这是函数名重名了。
只能将其中一个函数名更改才能进行操作。
解释:占位参数也必须填入数值才可以使用。
两者不是重载函数关系,且占位函数有了默认参数
int add(int x,int y)
{
return x + y;
}int add(int x,int = 0 )
{
return x + y;
}
1.当调用add(8,9)时,两者情况均可以,但编译器会认为这是函数名重名了。
2.在函数名重名情况下,调用add(8),也是错误的。
总结:占位参数与函数重载没有关系,要注意不要重名,以防发生错误。