关于重载详细分析参考:
http://www.cnblogs.com/skynet/archive/2010/09/05/1818636.html
内部机制涉及重载函数如何解决命名冲突,调用匹配的问题。
分辨重载的准则:
- 精确匹配:参数匹配而不做转换,或者只是做微不足道的转换,如数组名到指针、函数名到指向函数的指针、T到const T;
- 提升匹配:即整数提升(如bool 到 int、char到int、short 到int),float到double
- 使用标准转换匹配:如int 到double、double到int、double到long double、Derived*到Base*、T*到void*、int到unsigned int;
- 使用用户自定义匹配;
- 使用省略号匹配:类似printf中省略号参数
如果在最高层有多个匹配函数找到,调用将被拒绝(因为有歧义、模凌两可)。看下面的例子:
void print(int); void print(const char*); void print(double); void print(long); void print(char); void h(char c,int i,short s, float f) { print(c);//精确匹配,调用print(char) print(i);//精确匹配,调用print(int) print(s);//整数提升,调用print(int) print(f);//float到double的提升,调用print(double) print('a');//精确匹配,调用print(char) print(49);//精确匹配,调用print(int) print(0);//精确匹配,调用print(int) print("a");//精确匹配,调用print(const char*) }
定义太少或太多的重载函数,都有可能导致模凌两可,看下面的一个例子:
void f1(char); void f1(long); void f2(char*); void f2(int*); void k(int i) { f1(i);//调用f1(char)? f1(long)? f2(0);//调用f2(char*)?f2(int*)? }
这时侯编译器就会报错,将错误抛给用户自己来处理:通过显示类型转换来调用等等(如f2(static_cast<int *>(0),当然这样做很丑,而且你想调用别的方法时有用做转换)。上面的例子只是一个参数的情况,下面我们再来看一个两个参数的情况:
int pow(int ,int); double pow(double,double); void g() { double d=pow(2.0,2)//调用pow(int(2.0),2)? pow(2.0,double(2))? }
/*
*重载:两个或者多个函数有同一个函数名,不同数量的参数。
*当参数个数相同,参数类型不同,重载时会首先调用类型参数的函数,
*如果没有,则进行类型强制转换。
*/
#include <iostream>
using namespace std;
int ave(int n1, int n2);
double ave(double n1, double n2);
double ave(double n1, double n2, double n3);
int main()
{
cout << "The average of 2.0 2.5 3.0 is: "
<< ave(2.0, 2.5, 3.0) <<endl;
cout << "The average of 4.5 5.5 is:"
<< ave(4.5, 5.5) << endl;
cout << "The average of 5 8 is:"
<< ave(8, 5) << endl;
return 0;
}
int ave(int n1, int n2)
{
return (n1-n2);
}
double ave(double n1, double n2)
{
return ((n1+n2)/2.0);
}
double ave(double n1, double n2, double n3){
return ((n1+n2+n3)/3.0);
}
运行结果:
The average of 2.0 2.5 3.0 is: 2.5
The average of 4.5 5.5 is:5
The average of 5 8 is:3