C++泛型编程:函数模板与类模板

泛型编程是一种语言机制,通过他可以实现一个标准的容器库,可以处理不同的数据类型.
比如对栈的描述:
class stack
{
push(参数类型)//入栈
pop(参数类型)//出栈
}
由于上面的代码与数据类型有关,可以通过模板实现一个代码处理不同的数据类型。
首先执行一种通用的数据类型,不用具体指明哪一种。
class stack<参数模板 T>
{
push(T)//入栈
pop(T)//出栈
}
这里的参数模板T相当于一个占位符,当我们实例化类stack时,T会被具体的数据类型替换掉。

泛型在C++中的应用

泛型在C++中的主要实现为模板函数和模板类。
通常使用普通的函数实现一个与数据类型有关的算法是很繁琐的,比如两个数的加法:

int add(int a,int b) { return a+b; }
float add(float a,float b) { return  a+b; }

虽然在C++中可以通过函数重载来解决这个问题,但是函数重载是静态编译,运行时占用过多内存。
在此我们可以用C++的模板函数来表达通用型的函数,如下:

template<typename T> // 模板声明
T add(T a,T b) { return a+b; }  // 注意形参和返回值的类型

这时C++编译器会根据add函数的参数类型来生成一个与之对应的带具体参数类型的函数并调用。

#include 
using namespace std;
template <typename T>
T add(T a,T b)  //注意形参和返回类型
{   
 return a+b;
} 
void main()
{
    int num1, num2, sum; 
    cin>>num1>>num2;
    sum=add(num1,num2); //用int匹配模版参数T,若sum,num1,num2类型不一致则无法匹配。
    cout<<sum;
}

函数模板的写法

template
函数返回类型 函数名(形参列表)
关键字template 和typename是必须的,typename可以使用关键词class替换

  • 模板并不创建任何函数,而是告诉编译器如何定义函数。
  • 函数模板不允许自动类型转换。
  • 函数模板不可以设置默认模板实参。比如template 不可以。
  • 函数模板也可以向函数一样进行重载。

类模板的写法

//类声明部分,有两个模板参数T1,T2
template  <class T1, class T2 >  
class A {
   private:
   int a;
  T1 b;  //成员变量也可以用模板参数
  public: 
  int fun1(T1 x, int y );
 T2 fun2(T1 x, T2 y);
}
//类实现部分
template  <class T1, class T2 >
int A<T1>:: fun1(T1 x, int y ){//实现…… }
 template  <class T1, class T2 >
T2 A<T1,T2>:: fun2(T1 x, T2 y) {//实现…… }
 //使用类A
 int main( ) {
 //定义对象a,并用int替换T1, float替换T2
   A<int, float>  a;
   //实例化a,调用a的属性和方法……
}

由上例可以看出, 类模板参数T1,T2对类的成员变量和成员函数均有效。
在C++编程中,当你要实现的一个类的某些成员函数和成员变量的算法跟数据类型有关,可以考虑用类模板,且C++版的数据结构算法大都用类模板实现。

你可能感兴趣的:(C++,primer,泛型编程,函数模板,类模板)