### 重载函数

所谓重载函数是指多个函数具有相同的函数名称，而参数类型或参数个数不同。函数调用时，编译器以参数的类型及个数来区分调用哪个函数。

例如，下面的代码定义了两个重载函数。其程序代码如下：

int Add(int x ,int y) //定义第一个重载函数

{

printf("整型参数被调用\n"); //输出信息

return x + y; //设置函数返回值

}

double Add(double x,double y) //定义第二个重载函数

{

printf("实数参数被调用\n"); //输出信息

return x + y; //设置函数返回值

}

int main(int argc, char* argv[])

{

int ivar = Add(5,2); //调用第一个 Add 函数

float fvar = Add(10.5,11.4); //调用第二个 Add 函数

return 0;

}

执行上述代码，效果如图 1 所示。

图 1 函数重载

从图 1 中可以发现，语句“int ivar = Add(5,2);”调用的是第一个 Add 函数，而语句“float fvar = Add(10.5,11.4);”调用的是第二个 Add 函数。考虑这样一种情况，再定义一个 Add 函数，其参数类型为 float 类型。那么“float fvar = Add(10.5,11.4);”语句将调用哪个函数呢？

float Add(float x,float y) //定义第 3 个重载函数

{

printf("浮点参数被调用\n"); //输出信息

return x + y; //设置函数返回值

}

答案是调用第二个 Add 函数，如果改为如下的调用形式，则调用第 3 个重载函数。

float fvar = Add(10.5f,11.4f); //调用第 3 个 Add 函数

在定义重载函数时，应注意一下几点。

l 函数的返回值类型不作为区分重载函数的一部分

下面的函数重载是非法的。

int Add(int x ,int y) //定义一个重载函数

{

return x + y;

}

double Add(int x,int y) //定义一个重载函数

{

return x + y;

}

l 对于普通的函数参数来说 const 关键字不作为区分重载函数的标识

下面的函数重载是非法的。

bool Validate(const int x) //定义一个重载函数

{

return (x > 0) ? true : false;

}

bool Validate(int x) //定义一个重载函数

{

return (x > 0) ? true : false;

}

但是如果参数的类型是指针或引用类型，则 const 关键字将作为重载函数的标识。因此，下面的函数重载是合法的。

bool Validate(const int *x) //定义一个重载函数

{

return (*x > 0) ? true : false;

}

bool Validate(int *x) //定义一个重载函数

{

return (*x > 0) ? true : false;

}

l 参数的默认值不作为区分重载函数的标识

下面的函数重载是非法的。

bool Validate(int x = 20) //定义一个重载函数

{

return (x > 0) ? true : false;

}

bool Validate(int x) //定义一个重载函数

{

return (x > 0) ? true : false;

}

l 使用 typedef 自定义类型不作为重载的标识

当函数使用了 typedef 自定义的类型作为参数类型时，如果另一个函数的参数类型与自定义类型的原始类型相同，则函数的重载是非法的。例如：

typedef int INT; //自定义一个类型

bool Validate(INT x ) //定义一个重载函数

{

return (x > 0) ? true : false;

}

bool Validate(int x) //定义一个重载函数

{

return (x > 0) ? true : false;

}

上述代码的函数重载是非法的，因为 typedef 不是创建新的数据类型，因此编译器认为上面的两个函数属于同一个函数，不能区分重载函数。

l 局部域中声明的函数将隐藏而不是重载全局域中的函数

下面的代码定义了 3 个重载函数，但是在主函数内容前置声明了第 3 个重载函数，此时，第 3 个重载函数将隐藏而不是重载其他函数。下面代码中主函数 main 中的函数调用是非法的。

bool Validate(float x ) //定义第一个重载函数

{

printf("浮点参数函数\n"); //输出信息

return (x > 0) ? true : false;

}

bool Validate(int x) //定义第 2 个重载函数

{

printf("整型参数函数\n"); //输出信息

return (x > 0) ? true : false;

}

int main(int argc, char* argv[]) //主函数

{

bool Validate(double x); //前置声明第 3 个重载函数

Validate(10.5f); //视图调用第 2 个重载函数，导致错误，因为第 2 个函数被隐藏了

return 0;

}

bool Validate(double x,double y) //定义第 3 个重载函数

{

printf("实型参数函数\n"); //输出信息

return (x > y) ? true : false;

}

上述代码中，在 main 函数内部（独立域）前置声明了第 3 个重载函数，此时导致第一个、第 2 个函数被隐藏，语句“Validate(10.5f);”试图调用第 2 个重载函数，导致编译错误。为了能够访问被隐藏的函数，需要使用域运算符::，在 main 函数中将“Validate(10.5f);”语句修改为“::Validate(10.5f);”语句就可以通过编译了。