泛型编程
我们在编程过程中会经常使用一些很方便的算法,比如排序算法,查找算法等等,但是平时在我们使用的时候我们是根据自己需要的数据类型来写函数或者类,但是这样一来,代码的通用性就大大降低,在我们要对其他类型的数据做相同的操作时,我们必须将原先写好的函数或者类复制过来,然后将其中的数据类型改成我们需要的类型,这样子就会很麻烦!
所以我们就有了泛型编程的这样的概念,。所谓泛型(Genericity),是指具有在多种数据类型上皆可操作的含意。C++通过参数化类型来实现通用的容器。
函数模板:
定义形式
template<模板参数表>
类型名 函数名 (参数表)
{
函数体的定义
}
模板参数表构成
(1)class(或typename)标识符,表明可以接收一个类型参数。这些类型参数代表的是类型,可以使内部类型或者自定义类型。
(2)“类型说明符”标识符,指明可以接收一个由“类型说明符”所规定类型的常量作为参数。
(3)template<参数表>class 标识符,指明可以接收一个类模板作为参数。
例子:
冒泡排序
void Sort(int* p,int len)
{
for(int i=0;i<len-1;i++)
{
for(int j=0;j<len-1-i;j++)
{
if(p[j]>p[j+1])
{
int t=p[j];
p[j]=p[j+1];
p[j+1]=t;
}
}
}
}
这样子这个函数只适用于对int型数据来进行冒泡排序
template<typname T>
void Sort(T* p,int len)
{
for(int i=0;i<len-1;i++)
{
for(int j=0;j<len-1-i;j++)
{
if(p[j]>p[j+1])
{
T t=p[j];
p[j]=p[j+1];
p[j+1]=t;
}
}
}
}
这样上面代码就成为了一个函数模板,当我们要使用冒泡排序时,系统匹配该模板,并且自己生成一个对应数据类型的函数来进行排序,如此一来,代码的通用性就大大提高。
类模板:
定义形式
template<模板参数表>
class 类名
{
类成员声明
}
其使用形式与函数模板相同,将其中要改变的数据类型用模板参数表替换。
例子:
一个栈类模板
#pragma once
#include<cassert>
//模板的定义,SIZE为栈的大小
template<typename T,int SIZE=50>
class Stack
{
private:
T list[SIZE]; //数组,用于存放栈的元素
int top; //栈顶位置(数组下标)
public:
Stack()//构造函数,初始化栈
:top(-1)
{}
void push(const T& item) //将元素item压入栈
{
assert(!isFull()); //如果栈满了,则报错
list[++top] = item; //将新元素压入栈顶
}
T pop() //将栈顶元素弹出栈
{
assert(!isEmpty()); //如果栈为空,则报错
return list[top--]; //返回栈顶元素,并将其弹出栈顶
}
void clear() //将栈清空
{
top = -1; //清空栈
}
const T& peek()const //访问栈顶元素
{
assert(!isEmpty()); //如果栈为空,则报错
return list[top]; //返回栈顶元素
}
bool isEmpty()const //测试是否栈满
{
return top == -1;
}
bool isFull()const //测试是否栈空
{
return top == SIZE - 1;
}
~Stack()
{}
};
注:
模板不参与编译,所以一般写在.h文件中。