1.函数重载
允许参数个数不同、参数类型不同或两者兼而有之的两个以上的函数取相同的函数名。将两个或两个以上函数共用一个函数名,称为函数重载,这一组函数称为重载函数。如:
int max(int a1, int a2); int max(int a1, int a2, int a3); int max(int a1, int a2, int a3, int a4); int max(int a1, int a2, int a3, int a4, int a5); double max(double a1,double a2);
2.函数模板
如果一组重载函数仅仅是参数类型不一样,程序的逻辑完全一样,如果用一个符号代替类型,这组函数的代码完全相同。这一组函数可以写成一个函数,称为函数模板。
函数模板实现类型的参数化(泛型化),即把函数中的某些形式参数的类型设计成可变的参数,称为模板参数。在函数调用时,编译器根据函数实际参数的类型确定模板参数的值,用实际参数的类型取代函数模板中的模板参数,生成不同的模板函数。其实就是把函数中使用到的类型参数化。
//一 般的定义形式 template<typename AnyType> //该行指出要建立一个模板 void Swap(AnyType &a,AnyType &b) { AnyType temp; temp=a; a=b; b=temp; }
上述代码第一行指出要建立一个模板,并将类型命名为AnyType。关键字template和typename是必需的,除非可以使用关键字class代替typename。类型名也可以不用AnyType,好多程序员喜欢用T这种简单的名称。
在标准C++98添加关键字typename之前,C++使用关键字class来创建模板。也就是说,可以这样编写模板定义:
template<class AnyType> //该行指出要建立一个模板 void Swap(AnyType &a,AnyType &b) { AnyType temp; temp=a; a=b; b=temp; }typename关键字使得参数AnyType表示类型这一点更加明显;然而,有大量代码库是使用关键字class开发的。这种上下文中,这两个关键字是等价的。如果不考虑后向兼容问题,建议使用typename而不是class。
如果模板参数是类类型,尖括号中需要加前缀T,如:
//模板形式参数表可以包含基本数据类型,也可以包含类类型(需加前缀class) template<class T> T max(T a, T b) { return a>b ? a : b;}
如果没有模板,就需要为每种类型写一个函数。
int power(int base,int exponent) { int result=base; if(exponent==0) return (int)1; if(exponent<0) return (int)0; while(--exponent) result*=base; return result; }
double power(double base,double exponent) { double result=base; if(exponent==0) return (double)1; if(exponent<0) return (double)0; while(--exponent) result*=base; return result; }
应用例子:
#include<iostream> using namespace std; template<typename T> T max(T a,T b) { return a>b?a:b; } int main() { cout<<"max(3,5)="<<max(3,5)<<endl; //调用模板函数时,编译器将根据实际参数的类型确定模板参数的值,这里T为int型 cout<<"max(3.3,5.5)="<<max(3.3,5.5)<<endl;//这里T为double型 cout<<"max('d','r')="<<max('d','r')<<endl; return 0; }
在使用函数模板时,通常每个模板的形式参数都要在函数的形式参数表至少出现一次,这样编译器才能通过函数调用确定模板参数的值。如果某些模板参数在函数的形式参数表中没有出现,就需要显式指定模板实参来解决。如:
template<typename T1,typename T2,typename T3> T3 calc(T1 x,T2,y) { return x+y;// }
当调用cal(5,'c');时 ,编译器就无法推断出T3的类型,这时就需要显式告诉编译器这3个模板参数的实参类型,模板的实际参数放在一对尖括号中。如:
cal<int,char,char>(5,'c'); 运行结果是: 'f'
cal<int,char,int>(5,'c'); 运行结果是: 102