c语言中函数名字不可重复,但是可以写代码实现
普通的函数重载
这些同名函数的形参列表(参数个数 或 类型 或 顺序)必须不同和返回值没有关系(因为就像我想调用Add(1,2),Add重载的几个函数仅仅返回值不同,编辑器就不知道去找哪一个,就有歧义了)
情况1-数组
int ave(int*pa,int count)
和int ave(int pa[],int count);
不可重载
情况2-引用
int ave(int &a,int &b);
和int ave(int a,int b);
编译时候不报错
但是ave(100,200);
运行不报错,因为不可以用常量初始化引用
int a=100,b=200;
ave(a,b); //运行时候报错,因为有歧义,不知道走哪个函数
情况三-强制类型转换
float ave(float a,float b);
int ave(int a,int b);
float a=1.0f,b=2.0f;
ave((int)a,(int)b); //依然是走float,因为强制类型转换后的变量是临时变量,无固定的内存地址,则搞不了引用
情况4-const常量
int ave(int a,int b);
int ave(const int a,const int b);
不可重载,属于函数的const 常量,形同虚设了,编辑器还是会歧义
情况5-const常量引用
int ave(int &a,int &b);
int ave(const int &a,const int &b);
不会歧义,因为第二个函数需要两个const常量来初始化
情况6-函数默认参数
int ave(int a=1,int b=2);
float ave(float a=1.0f,float b=2.0f);
不行,编辑器又歧义了
函数模板(c++专属)
#include<iostream>
using namespace std;
template<typename type1>
type1 ave(type1 a, type1 b)
{
type1 x = a;
return (a + b + x) / 3;
}
int main() {
cout << ave(1, 2) << endl;
cout << ave(1.4, 1.6) << endl;
return 0;
}
也可以搞成指针
type1 *a
c = *ave(&a,&b,&c);
也可以强制指定
cout << ave<float>(1.4, 1) << endl; //参数部分会涉及强制类型转换
址传递的困惑
正常值传递
#include<iostream>
using namespace std;
template<typename type1>
void swap(type1* a, type1* b)
{
type1 temp;
temp = *a;
*a = *b;
*b = temp;
}
int main() {
int a = 1, b = 3;
swap(&a,&b);
cout << a << " " << b << endl;
return 0;
}
但是这样就失去了模板的意义,就只能搞指针
#include<iostream>
using namespace std;
template<typename type1>
void swap(type1 a, type1 b)
{
type1 temp;
temp = *a;
*a = *b;
*b = temp;
}
int main() {
int a = 1, b = 3;
swap(&a,&b);
cout << a << " " << b << endl;
return 0;
}
我们很多人会以为是这样写,但是这样的话模板就分不清楚,到底是引用还是指针,而且还报错了
编译器默认成引用了
对于这样有歧义的情况,我们也有对策-可以单独列出例外情况,因为函数重载优先级大于函数模板
但是要是把哪个重载的函数改为void返回值,编译器会报错,要和前面模板一个形式
也可以解决这个问题
所以在处理函数模板例外情况时候,不加template<>
限制会更加灵活