C++学习之:函数重载与函数模版

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





猜你喜欢

转载自blog.csdn.net/wu_qz/article/details/80145855