使用模板可以创建可重用的代码。
模板可以分为两类,一个是函数模板(通用函数),另外一个是类模板(通用类)。
函数模板定义了一组应用于不同数据类型的通用运算。
- 使用关键字 template 来创建.
template <class Type> ret-type func-name(parameter list){ //.. } //或者 template <class Type> ret-type func-name(parameter list){ //.. }
其中,Type 是一个占位符,代表函数使用的数据类型.
#include <iostream> using namespace std; //模板函数: 交换两个变量的值。 template <class X> void swap(X &a, X &b){ X temp; // 用X来代表通用的数据类型. temp=a; a=b; b=temp; } int main(){ int i1=10,i2=20; double dbl1=3.3,dbl2=8.8; char ch1='a',ch2='b'; swap(i1,i2); swap(dbl1,dbl2); swap(ch1,ch2); return 0; }
模板类定义了在类中使用的全部算法。
创建模板类
template <class Ttype> class class-name{ // } //或者 template <class Ttype> class class-name{ // }
其中 Ttype 是类型名字占位符, 在实例化类的时候将使用指定的数据类型来替换.
如果需要使用多个通用数据类型,使用逗号分割参数列即可.
创建模板类的一个实例
class-name <type>ob;
type 是对象需要使用的数据类型.
模板类的成员函数也将自动成为模板函数,不需要使用template 来声明他们。
======= 补充说明=======
模板函数,再举例: 取<最大值>
template <class Type>
Type MAX(Type a, Type b)
if(a>b)
return a;
else
return b;
}
int main(){
int iMax=MAX<int>(10,12);
long lMax=MAX<long>(10,12);
double dMax=MAX>double>(10.0,12.0);
return 0;
}
当调用模板函数的时候,需要把类型(Data Type) 作为参数提供给函数.
模板是一种编译时(compile-time)结构,并且会根据所指定的不同类型进行扩展。
模板函数提供了一种编写类型安全,可复用代码的优良机制。
模板类提供了一种类似于预处理的替换技术,运行编写可复用的,类型安全的类。
基于模板的堆栈(Stack)类。
- Stack 提供一个LIFO结构,栈里面存储的是相同数据类型 的元素.
- 采用模板的Stack类,可以存储任何类型的数据。
#include <iostream> using namespace std; template <class Ttype> class Stack{ private: Ttype m_data[100]; short m_sPos; public: Stack(); ~Stack(); void Push(Ttype value); Ttype Pop(); bool IsEmpty(){ return(m_sPos==0); } bool HasElements(){ return(m_sPos!=0); } bool IsFull(){ return(m_sPos==100); } }; template <class Ttype> Stack<Ttype>::Stack(){ m_sPos=0; } template <class Ttype> Stack<Ttype>::~Stack(){ } template <class Ttype> void Stack<Ttype>::Push(Ttype value){ m_data[m_sPos++]=value; } template <class Ttype> Ttype Stack<Ttype>::Pop(){ return m_data[--m_sPos]; } int main(){ //创建double类型栈。 Stack<double> doubleStack; doubleStack.Push(1.1); doubleStack.Push(2.0); doubleStack.Push(3.0); while(doubleStack.HasElements()){ cout<<doubleStack.Pop()<<endl; } //动态创建long类型的栈 Stack<long> *plongStack=new Stack<long>; plongStack->Push(1000); plongStack->Push(2000); while(plongStack->HasElements()){ cout<<plongStack->Pop()<<endl; } delete plongStack; return 0; }
ATL 如何使用模板?ATL 如何适用模板技术在基类里访问成员函数?
注意,ATL 在覆盖基类特性的时候没有使用虚函数。
如下:CComObject 通过把基类作为一个模板参数进行传递并使用该类型对类实现指针进行类型转换,可以得到指向基类实现的一个直接指针。
#include <iostream> using namespace std; class CBase{ public: CBase(){} ~CBase(){} void BaseMethod(){ cout<<"BaseMethod in Base"<<endl; } }; class CMath:public CBase{ public: CMath(){} ~CMath(){} void BaseMethod(){ cout<<"BaseMethod in CMath"<<endl; } }; template<class T> class CComObject:public T{ public: CComObject(){} ~CComObject(){} void CallBaseMethod(){ T *pT=static_cast<T*>(this); pT->BaseMethod(); } }; int main(){ CComObject<CMath> *pMath=new CComObject<CMath>; pMath->CallBaseMethod(); delete pMath; return 0; }