template的用法(转载)---希望对大家有用
来源:互联网 发布:汉服好的淘宝店铺推荐 编辑:程序博客网 时间:2024/05/16 00:25
-- template 的用法
在程式设计当中经常会出现使用同种数据结构的不同实例的情况。例如:在一个程式中
能使用多个队列、树、图等结构来组织数据。同种结构的不同实例,也许只在数据元素
的类型或数量上略有差异,如果对每个实例都重新定义,则非常麻烦且容易出错。那么能
否对同种类型数据结构仅定义一次呢?答案是肯定的,C++提供的类模板(Class Template
)就能实现该功能。
一、类模板
类模板是C++提供的一种特别机制,通过他我们能定义一种特别的类(称为模板类),在类
的定义中能包含待定的类型参数,在声明类的实例时,系统会自动根据传递的类型生成
用户想要生成的类实例。下面是用C++实现的一个简单的模板类Clist的定义。
Template <class T, int I> class CList
{
public:
int SetItem(int Index, const T &Item);
int GetItem(int Index, T &Item);
private:
T Buffer;
}
在这里,T是类型参数,I是整型常量参数。T和I的实际值是在声明具体类实例时指定的。
模板类的<>号内能包括任意个类型参数和常量参数(至少要有一个参数)。类型参数和
常量参数能是所有合法的标准类型和用户自定义类型,包括简单类型及各种结构体。同
其他类相同,类成员函数SetItem的实现能在类定义内完成,也能在类CList定义处实
现:
template<class T, int I> int CList<T, I>::SetItem(int Index, const T &Item)
{
if ( (Index<0)||(Index>I-1) )
return 0; // 出错
Buffer[Index]= Item ;
return 1; // 成功
}
值得注意的是,在类定义外完成函数实现时,必须以关键字template和类模板定义中相同
的参数表(<>号内的)开头(上例为template<class T, int I>),并且范围分解操作符前的
类名后应跟上模板参数名清单(上例为CList<T, I>)。另外,和非模板类不同的是,必须将
函数实现包括在调用他的每个源文件中,使编译器能从函数实现产生代码。通常的做法是
将模板类的函数实现也放在定义该类的头文件中,这样只需在调用的源文件中包含该头文
件即可。
那么,怎么使用生成特定的类实例呢?我们能像使用其他类相同来使用模板类,不过必须
指定模板参数的值。例如采用如下声明:
CList <int, 100> IntList;
则使IntList成为CList类的实例,每次出现的T参数都换成int, 每次出现的I参数都换成
100。这样,IntList类中的Buffer就是个长度为100的整型数组,SetItem和GetItem函数
参数是int值的引用。例:
IntList.SetItem(0, 5); //给数组第一个元素赋为整数5
模板类还能像其他类相同能定义构造函数和析构函数。下面我们以一种简单的数据
结构??堆栈为例,来说明怎么用类模板来构造通用数据结构。
二、 利用类模板实现通用堆栈结构
所有抽象数据结构在计算机中的实现,归根结底都只有两种方式:顺序存储(用数组实现)
,链式存储(用指针实现)。堆栈也不例外,按其实现方式可分为顺序栈(用数组实现)和链
栈(用指针实现)。
1. 通用顺序栈的实现
因为顺序栈中的元素在空间上连续存储,栈顶的元素位置需要注明,所以构造顺序栈的模
板类应该有这样的一些成员变量:一个待定类型和长度的数组Buffer,一个记录栈顶元素
的数组下标的整型变量top。堆栈的基本操作主要有:入栈(Push)、出栈(Pop)、置空(Se
tEmpty)、判断当前状态(IsEmpty)等,他们应用模板类的成员函数来实现。作为一个标准
的类,他还应该有自己的构造函数和析构函数。具有这些功能的模板类,就能作为一个
通用的顺序栈来使用了。该类的定义如下:
template <class T,int SIZE> class CArrayStackTemp
{
public:
CArrayStackTemp () //缺省构造函数,构造一个空堆栈
{
top= -1;
};
~ CArrayStackTemp (){};//析构函数
void SetEmpty (); //置空堆栈
bool IsEmpty(); //判断堆栈是否为空
bool Push(T element); //入栈
bool Pop(T& element);//出栈
private:
T Buffer[SIZE];
int top;
};
和堆栈的基本操作相对应的成员函数的实现如下:
template <class T, int SIZE> void CArrayStackTemp<T, SIZE>:: SetEmpty ()
{
top= -1; //将栈顶指针赋 -1,并不实际清除数组元素
}
template <class T, int SIZE> bool CArrayStackTemp<T, SIZE>:: IsEmpty ()
{
return(top == -1);
}
template <class T, int SIZE> bool CArrayStackTemp<T, SIZE>:: Push (T element
)
{
top++;
if (top>SIZE-1)
{
top--;
return false; //堆栈已满,不能执行入栈操作
}
Buffer[top]=element;
return true;
}
template <class T, int SIZE> void CArrayStackTemp<T, SIZE>:: Pop (T& element
)
{
if (IsEmpty())
return false;
element =Buffer[top];
top--;
return true;
}
根据实际需要,还能扩充堆栈功能。例如:加入取栈顶元素、求堆栈长度等操作,其方法
如上。
2. 通用链栈的实现
模板类中允许使用指针和定义自己的结构,这就为实现链式结构提供了确保。这里采用一
个单链表来实现堆栈,栈顶指针指向链表的第一个结点,入栈和出栈均在链表的头进行。
该模板类的定义如下:
template <class T> class CLinkStackTemp
{
public:
//类的缺省构造函数,生成一个空堆栈
CLinkStackTemp ()
{
top=NULL;
};
~ClinkStackTemp(){}; //析构函数
//定义结点结构
struct node
{
T
data; //入栈元素
node* next; //指向下一结点的指针
};
void SetEmpty(); //置空堆栈
bool IsEmpty(); //判断堆栈是否为空
bool Push(T element); //压入堆栈
bool Pop(T& element);//弹出堆栈
private:
node* top;
};
该类的成员函数实现如下:
template <class T> void CLinkStackTemp <T>::SetEmpty()
{
//释放堆栈占用的内存
node* temp;
while (top!=NULL)
{
temp=top;
top=top->next;
delete temp;
}
}
template <class T> bool CLinkStackTemp <T>::IsEmpty()
{
return (top==NULL);
}
template <class T> bool CLinkStackTemp <T>::Push(T element)
{
node* temp=new node();
if (temp ==NULL)
return false ;
temp->data=element;
temp->next=top;
top=temp;
return true;
}
template <class T> bool CLinkStackTemp <T>::Pop(T& element)
{
if ( IsEmpty())
return false;
node* q = top;
element = top->data;
top=top->next;
delete q;
return true;
}
和顺序栈的实现略有不同,链栈不必指定栈的容量,其大小能是近似"无限"的。为了程
序的使用方便,我们同样能加入一些增强的功能。
三、 通用堆栈类的使用
通用堆栈类的使用较为简单,堆栈类的实例就是个能方便使用的堆栈。对堆栈的操作
都是通过类的成员函数来实现的。使用的具体步骤如下:
1. 在要使用堆栈类的程式代码的文件开头包括模板类及其成员函数的定义。
2. 类的实例化,可声明成变量,也能声明他的指针,如:
CArrayStackTemp <int, 100> intStack; //生成一个长度为100的int型堆栈
//生成一个元素为Record型的堆栈,Record为自定义结构
CLinkStackTemp <Record>* RecordStack;
RecordStack=new CLinkStackTemp<Record>;
应注意在定义顺序栈时,必须指定栈的大小,而链栈则不必。另外在指定指针类型和执行
new操作时,必须对模板参数赋值,并且前后要一致。
3. 对堆栈进行操作,如:
intStack.Push(3); //将整数3入栈
RecordStack.SetEmpty(); //将堆栈置空
无论我们使用哪种堆栈类,对用户来讲都是透明的,操作起来并无差别。
- template的用法(转载)---希望对大家有用
- 总结一下SHFileOperation的用法,希望对大家有用
- 转载的,给大家分享,,希望有用
- 指针-----希望对大家有用
- sql的一些基础,希望对大家有用!
- 关于objective-c的内存管理(希望对大家有用)
- Android一个小球弹跳的例子,希望对大家有用
- 触发器,网上搜到的 希望对大家有用
- Android一个小球弹跳的例子,希望对大家有用
- 自己总结的一套JavaScript,希望对大家有用
- 去掉xcode源码末尾的空格【转载的这篇还没有具体操作过,希望对大家有用】
- [推荐]精品代码收藏(希望对大家有用)
- 精品代码收藏(希望对大家有用)
- 精品代码收藏(希望对大家有用)
- 杀毒软件下载,希望对大家有用
- RTSP协议中文版,希望对大家有用!
- 中兴工程师周老师对我的解惑,希望对大家也有用!!
- 本人常用的VIM快捷键的记录,备忘,希望对大家有用
- 看书
- oracle 返回 数据集
- apt-get install python2.6-dev to fix "Python.h: No such file or directory"
- » 转载请注明来源:贰号楼肆层 » 《关于Maven无法正确处理javac中文警告信息的问题》
- 诊断索引健全性的新工具
- template的用法(转载)---希望对大家有用
- DDOS拒绝服务攻击原理
- 如何使用不同的用户登录到共享文件夹
- 求泰坦之旅tqelysion中文版下载
- test
- flex 中 raido buttion 在datagrid 中选不中的问题
- SQL Server 2008的逻辑查询处理步骤
- 昨天去蠡湖公园放风筝, 无锡的天气比上海凉快^_^
- Ext TREE 除node外再绑定参数