第一次非亲密接触
C++模板技术
在这个初级教程里,我将向大家介绍C++模板技术的基础知识。使用模板技术可以使你在开发大中型应用软件的过程中节省很多时间,简单地说,模板技术是一种使用相同的代码来实现不同的函数和类的技术。通过定义模板函数和模板类,使不同的函数和类共享同一段代码成为可能,从而提高了开发效率。
想象一下,你拥有一个堆栈类(CStack),它有入栈、出栈、读取等功能,它用于double类型,OK,它看起来可以很好的工作,可是某天由于某种需求,你希望它对CString类型也有效,或者int,或者其他你自己定义的类型,该怎么办呢?通常情况下你只能选择拷贝、粘贴代码来实现每个不同类型的Cstack类,效率十分低。如果你使用模板机制,你只需实现一次Cstack类代码就可以满足不同数据类型的需求。好,让我们走进模板的世界,看看它是如何工作的。
模板函数
让我们假定我们需要一个在不同数据类型的数组里搜寻最小值的模板函数,代码如下:
template < class ElemType >
ElemType calcmin(ElemType elemField[], int iFieldSize)
{
int iMin = 0;
for (int i=1; i < iFieldSize; ++i)
{
if (elemField[i] < elemField[iMin])
iMin = i;
}
return elemField[iMin];
}
使用这个模板函数的函数代码如下:
void LetsTestTheFunctionTemplate()
{
int iField[] = {1,2,3,4,5,6};
double dField[] = {2.5, 2.31, 10.23, 15.2};
int iSize1 = sizeof(iField) / sizeof (int);
int i = calcmin(iField, iSize1);
int iSize2 = sizeof(dField) / sizeof(double);
double d = calcmin(dField, iSize2);
}
上述例子中使用了两种数据类型:int和double数组,使用同样的模板函数来返回最小值。
模板函数也可以声明为内联inline, 外部extern 或者 静态static。声明时将这些关键字放在关键字template和它的参数后边,如:
template < class ElemType >
inline ElemType swap(ElemType& a, ElemType& b);
模板类
定义一个模板类与定义一个模板函数类似,让我们用我最开始举的堆栈类(CStack)例子来说明模板类的定义,类定义原型如下:
template < typename ElemType, int iSize=100 >
class Stack
{
public:
Stack();
~Stack();
void push(const ElemType& anElement);
void pop(ElemType& anElement);
bool wasError() const;
bool isEmpty() const;
private:
ElemType elems[iSize];
int iTop;
bool bErrorOccd;
};
它的实现代码与普通类的实现代码没有太大的不同,只不过是加了点稍微复杂的符号而已。你需要在每个成员函数的实现代码前面加上template关键字及<>内的参数原型,并且类名后面加上<>及其内部的参数,但不必声明参数,因为在template<>中已经声明,具体如下:
template < class ElemType, int iSize >
Stack< ElemType, iSize >::Stack()
: iTop(0), bErrorOccd(false)
{
}
template < class ElemType, int iSize >
Stack< ElemType, iSize >::~Stack()
{
}
template < class ElemType, int iSize >
void Stack< ElemType, iSize >::push(const ElemType& anElement)
{
bErrorOccd = (iTop == iSize);
if (!bErrorOccd)
elems[iTop++] = anElement;
}
template < class ElemType, int iSize >
void Stack< ElemType, iSize >::pop(ElemType& anElement)
{
bErrorOccd = (iTop == 0);
if (!bErrorOccd)
anElement = elems[--iTop];
}
template < class ElemType, int iSize >
bool Stack< ElemType, iSize >::wasError() const
{
return bErrorOccd;
}
template < class ElemType, int iSize >
bool Stack< ElemType, iSize >::isEmpty() const
{
return (iTop==0);
}
你可以像下面这样定义一个Stack模板类的对象:
Stack< int > iTheIntStack;
Stack< double, 30 > dTheDoubleStack;
待续
下一部分中我将给大家介绍模板技术的高级特性,如嵌套模板,友元模板等。