1、基本概念

所谓泛型编程:以独立于任何特定类型的方式编写代码。使用泛型程序时,我们需要提供具体程序实例所操作的类型或值。标准库的容器、迭代器和算法都是泛型编程的例子。每种容器(如:vector)都有单一的定义,但可以支持定义许多不同种类的vector,他们的区别在于所包含的元素类型。

模板是泛型编程的基础。

泛型编程与面向对象编程一样,都依赖于某种形式的多态性,面向对象编程依赖的多态性称为运行时多态性,泛型编程依赖的多态性称为编译时多态性或参数多态性。对于运行时多态性,只要使用基类的引用或指针,基类类型或派生类类型的对象就可以使用相同的代码。在泛型编程中,我们所编写的函数和类能够多态的用于跨越编译时不相关的类型。一个类和一个函数可以用来操纵多种类型的对象。

C++中,模板是泛型编程的基础,模板是创建类或函数的蓝图或公式。如标准库定义了一个类模板vector,可以产生任意数量的特定类型的vector类,如vector<int>vector<string>

2、模板定义

1.举例

1int compare(const string &v1, const string &v2)

{

if(v1<v2) return -1;

if(v2<v1) return 1;

return 0;

}

2int compare(const int &v1, const int &v2)

{

if(v1<v2) return -1;

if(v2<v1) return 1;

return 0;

}

(3) int compare(const double &v1, const double &v2)

{

if(v1<v2) return -1;

if(v2<v1) return 1;

return 0;

}

我们可以用函数重载来实现不同类型的比较,但是观察可知,上述3个函数只有形参不同,函数体是相同的,我们可以用函数模板来实现任意类型数据的比较。不仅仅是3种类型,如果希望此函数用于未知类型,只能用函数模板了。

2、函数模板定义

函数模板是一个独立于类型的额函数,可作为一种方式,产生特定的函数版本。

template <typename T>

int compare(const T &v1, const T &v2)

{

if(v1<v2) return -1;

if(v2<v1) return 1;

return 0;

}

模板定义以关键字template开始,后接模板形参表,模板形参表是用尖括号扩住的一个或多个模板形参的列表,形参之间以逗号分隔。

模板形参表不能为空。

模板形参表

模板形参可以是表示类型的类型形参,也可以是表示常量表达式的非类型形参。

类型形参在关键字classtypename后面定义。非类型形参在类型说明符之后声明。

其中,在此,关键字classtypename没有区别。

使用函数模板

使用函数模板时,编译器会推断那个模板实参绑定到形参,一旦编译器确定了实际的模板实参,就称它例化了函数模板的一个实例。

用实参的类型推断出类型形参的类型。

int a = 10; int b= 11;

compare(a, b);

变量aint型,推出形参const T &v1中的Tint型,同理得到const T &v2中的形参为int。然后根据函数形参的类型推断出模板形参的类型,对应的typename T 中的Tint,然后把模板函数中所有的T都换做int。称为实例化了函数模板的一个实例。

5 inline 函数模板

inline关键字要在模板形参表之后,返回类型之前,不能放在关键字template之前。如:

template <typename T> inline T min(const T&, const T&);

3、定义类模板

举个例子:

template <typename Type> class Queue

{

public:

Queue();

Type &front();

const Type &front() const;

void push(const Type &);

void pop();

bool empty() const;

private:

//.....

};

//成员函数的实现

template <typename Type> void Queue<Type>::push(const Type &v1)

{

//....

总结:

函数模板是建立算法库的基础。类模板是简历标准库容器和迭代器类型的基础。

模板和虚函数应该是不能掺杂在一起的。