65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.50/5 (37投票s)

2002年7月18日

2分钟阅读

viewsIcon

258160

关于基本函数和类模板的文章。

引言

当开发大型应用程序时,通过为不同的函数和类使用共享代码,模板可以为您节省大量时间。 从定义上讲,模板是通用的函数或类,它们独立于数据类型工作。 在这个入门教程中,我将处理模板函数和模板类。 假设您已经实现了一个类,该类处理一个堆栈及其所有工作,包括推送、弹出、读取状态等等。 这个堆栈类可以处理 double 值。 但是,如果您稍后在同一程序中需要一个用于 intCstring 或其他类型的堆栈怎么办? 如果没有模板机制,您必须为每个堆栈类复制和粘贴代码。 这不是很有效。 但是使用模板,您只需定义具有其所有自身函数和变量的模板函数或类,并声明一个新变量,该变量从模板定义中获取所有内容。 因此,让我们看看它是如何工作的。

函数模板

假设我们需要一个函数模板,用于从不同类型的数组中搜索最小值

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[],但为每种数据类型提供相同的功能,即在数组中搜索最小值并返回它。

函数模板也可以声明为 inlineexternstatic。 这样做时,重要的是将字段放在关键字 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;

待续...

在第二部分中,我将处理更高级的模板功能,例如模板中的模板,在模板中使用友元定义以及其他一些内容...

许可证

本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。

作者可能使用的许可证列表可以在此处找到。

© . All rights reserved.