概述
重载函数
现实生活中的一个词可能有多种含义,比如,洗衣服、洗头、洗车,都有一个洗字,但是他们的操作方式是不一样的。函数也一样,有时候它们的操作不完全一样但是名字一样,这就是重载函数。
重载函数就是,两个以上的函数取相同的函数名,但是函数形参的个数或者类型不同,编译器会根据实参与形参的类型和个数进行最佳匹配,自动确定调用哪一个函数。
为什么要有重载函数呢?因为如果没有重载函数,那么对不同类型的数据进行类似的操作也要定义不同名称的函数,比如加法函数,就必须对整数加法和浮点数加法分别定义不同的函数名:
int nadd(int a, int b);
float fadd(float a, float b);
这样调用需要记住的函数名太多,而且功能类似,很不方便。
形参类型不同的例子:
int add(int x,int y);
float add(float x,float y);
形参个数不同的例子:
int add(int x,int y);
int add(int x,int y,int z);
在这里要提醒几个需要注意的地方:
1.重载函数的形参不管是类型还是个数必须有一样是不同的。因为编译器就是看实参和哪个函数的形参的类型及个数匹配,来判断调用哪个函数,如果函数名、形参类型和个数相同,即使函数返回值类型不同,编译器也会认为是函数重复定义的语法错误,就是说它认为是一个函数。以下两种是错误的重载函数:
int add(int x,int y);
int add(int a,int b);
上面两个函数虽然形参名不同,但是编译器不会以形参名来区分函数,它会认为这是一个函数。我们以后也要记住,若只改变形参名则函数不会变,调用的地方也不必变。
int add(int x,int y);
void add(int x,int y);
上面这两个函数返回值不同,确实是两个函数,但是编译器也不会以返回值来区分函数,也会认为是重复定义。
2.重载函数都是进行类似的操作,不要把不同的功能定义成重载函数,否则会让人对调用有误解,比如:
int add(int x,int y)
{
return x+y;
}
float add(float x,float y)
{
return x-y;
}
这两个函数一个是实现的两个数的加法,一个是实现减法,在语法上并没有问题。但是功能不一样但是都叫add,我们调用的时候是不是会混淆?
#include<iostream>
using namespace std;
int add(int m,int n); // 函数调用前必须先声明函数原型
float add(float x,float y);
int main()
{
int m, n;
float x, y;
cout<<"Enter two integer: ";
cin>>m>>n;
cout<<"integer "<<m<<'+'<<n<<"="<<add(m,n)<<endl;
cout<<"Enter two float: ";
cin>>x>>y;
cout<<"float "<<x<<'+'<<y<<"= "<<add(x,y)<<endl;
return 0;
}
int add(int m,int n)
{
return m+n;
}
float add(float x,float y)
{
return x+y;
}
函数模板
有时候我们使用重载函数还不能达到最优的效果,比如,两个求绝对值的函数:
int abs(int x)
{
return x<0 ? -x:x;
}
double abs(double x)
{
return x<0 ? -x:x;
}
大家观察下这两个函数,这两个函数只是返回值类型和参数类型不同,功能完全一样,如果能有办法写一段通用的代码适用于多种不同的数据类型,就是不用像上面那样写两个函数而只是一段代码就能实现两个函数的功能,那代码的复用性不是更高了吗?开发效率也会提高的。这就要函数模板来实现了。
模板是有可以使用和操作任何数据类型的通用代码构成,这种程序设计叫做参数化程序设计,因为它把数据类型当成了参数,可以用来创建一个通用功能的函数,支持多种不同类型的形参和返回值。函数模板的定义形式是:
template <typename 标识符>
函数定义
求绝对值的函数模板示例:
#include<iostream>
using namespace std;
template <typename T>
T abs(T x)
{
return x<0 ? -x:x;
}
int main()
{
int n = 5;
double d = -2.3;
cout << abs(n) << endl;
cout << abs(d) << endl;
return 0;
}
编译器会根据调用abs函数时传入实参的类型来确定函数模板的类型参数是什么类型。上面使用调用表达式abs(n)时,因为n是int类型,所以模板中类型参数T就是int,然后编译器会以函数模板为样板生成一个函数:
int abs(int x)
{
return x<0 ? -x:x;
}
同样,对于调用表达式abs(d),因为d是double类型,所以类型参数T就是double,编译器会根据函数模板生成下面的函数:
double abs(double x)
{
return x<0 ? -x:x;
}
所以,abs(n)实际上调用的是函数模板生成的函数:int abs(int x)
。而abs(d)调用的是由函数模板生成的函数:double abs(double x)
。
最后
以上就是舒服啤酒为你收集整理的重载函数与函数模板的全部内容,希望文章能够帮你解决重载函数与函数模板所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复