函数重载(Function Overload):用同一个函数名定义不同的函数,当函数名和不同的参数搭配时函数的含义不同。
在C语言中,无法实现重载,只能使用函数指针
void func(int a)
{
cout<<"func"<<endl;
cout<<a<<endl;
}
int main(void)
{
//定义一个 指向void func(int a)的函数指针
void (*fp)(int) = func;//fp就是执行void()(int)这种函数类型的指针
//第二个()代表指定参数类型
fp(10);
}
1.重载规则
- 函数名相同。
- 参数个数不同,参数的类型不同,参数顺序不同,均可构成重载。
- 返回值类型不同则不可以构成重载。
//函数重载,就是对参数列表的变换,不是函数返回值的变化
//返回值必须一样,参数列表不同,并且函数名相同的函数都是重载函数
//如果说函数重载加上了默认参数,并且函数名相同,就出现二义性
//记住:函数重载最好不要有默认参数
void func(int a);//ok
void func(char a);//ok
void func(char a,int b);//ok
void func(int a, char b);//ok
char func(int a);//与第一个函数有冲突
2.调用准则
编译器调用重载函数的准则:
- 将所有同名函数作为候选者
- 尝试寻找可行的候选函数
精确匹配实参
- 通过默认参数能够匹配实参
- 通过默认类型转换匹配实参
匹配失败
- 最终寻找到的可行候选函数不唯一,则出现二义性,编译失败。
- 无法匹配所有候选者,函数未定义,编译失败。
3.重载底层实现(name mangling)
C++利用 name mangling(倾轧)技术,来改名函数名,区分参数不同的同名函数。
实现原理:用vcifld表示 **void char int float long double **及其引用。
void func(char a);//func_c(char a)
void func(char a,int b, double c);//func_cid(char a, int b, double c)
4.函数指针
定义函数指针
void func(int a,int b)
{
cout<<a<<b<<endl;
}
void func(int a,int b,int c)
{
cout<<a<<b<<c<<endl;
}
void func(int a,int b,int c,int d)
{
cout<<a<<b<<c<<d<<endl;
}
//1.定义一个函数类型
typedef void(myfunctype)(int ,int);//定义一个函数类型,返回值是void,参数列表是int,int, void()(int,int)
//2.定义一个函数指针类型
typedef void(*myfunctype_pointer)(int,int);//定义了一个函数指针类型,返回值是void,参数列表是int,int, void()(int,int)
int main(void)
{
//1.定义一个函数指针
myfunctype *fp1 = NULL;
fp1 = func;
fp1(10,20);
//2.定义一个函数指针
myfunctype_pointer fp2 = NULL;
fp2 = func;
fp2(10,20);
//3.直接定义一个函数指针
void(* fp3)(int,int) = NULL;
fp3 = func;
fp3(10,20);
cout<<"---------------------------------------------"<<endl;
//此时fp3是void(*)(int,int)
// fp3(10,20,30,40);//fp3是恒定指向一个函数入口,值指向了(int,int)
// fp3(10,20,30);//想通过函数指针,发生函数重载,是不可能的!!
fp3(10,20);
void(* fp4)(int,int,int) = func;//在对函数指针赋值的时候,函数指针会根据自己的类型,找到一个重载函数
fp4(10,10,10);
return 0;
}
5.重载总结
- 重载函数在本质上是相互独立的不同函数。
- 函数的函数类型是不同的
- 函数返回值不能作为函数重载的依据
- 函数重载是由函数名和参数列表决定的。
网友评论