模板初学者指南 - 第 1 部分






4.50/5 (37投票s)
2002年7月18日
2分钟阅读

258160
关于基本函数和类模板的文章。
引言
当开发大型应用程序时,通过为不同的函数和类使用共享代码,模板可以为您节省大量时间。 从定义上讲,模板是通用的函数或类,它们独立于数据类型工作。 在这个入门教程中,我将处理模板函数和模板类。 假设您已经实现了一个类,该类处理一个堆栈及其所有工作,包括推送、弹出、读取状态等等。 这个堆栈类可以处理 double 值。 但是,如果您稍后在同一程序中需要一个用于 int
、Cstring
或其他类型的堆栈怎么办? 如果没有模板机制,您必须为每个堆栈类复制和粘贴代码。 这不是很有效。 但是使用模板,您只需定义具有其所有自身函数和变量的模板函数或类,并声明一个新变量,该变量从模板定义中获取所有内容。 因此,让我们看看它是如何工作的。
函数模板
假设我们需要一个函数模板,用于从不同类型的数组中搜索最小值
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);
}
模板 min
被用于两种不同的数据类型,int[]
和 double[]
,但为每种数据类型提供相同的功能,即在数组中搜索最小值并返回它。
函数模板也可以声明为 inline
、extern
或 static
。 这样做时,重要的是将字段放在关键字 template
及其参数之后
template < class ElemType >
inline ElemType swap(ElemType& a, ElemType& b);
类模板
定义类模板几乎与定义函数模板类似。 让我们赶上我在开头使用的示例,即用于处理不同数据类型堆栈的通用堆栈类。 原型将定义如下
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;
};
实现与正常的类实现没有太大区别,只不过符号稍微复杂一些。 定义类模板后,可以像普通类一样使用它,但必须在 <
和 >
中指定参数,并且在模板中可以使用不带参数的类名。 因此,让我们看一下堆栈示例的实现
// include your prototype here or use a #define
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< int > iTheIntStack;
Stack< double, 30 > dTheDoubleStack;
待续...
在第二部分中,我将处理更高级的模板功能,例如模板中的模板,在模板中使用友元定义以及其他一些内容...
许可证
本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。
作者可能使用的许可证列表可以在此处找到。