CList 类

在程序设计当中经常会出现使用同种数据结构的不同实例的情况。例如:在一个
程序中可以使用多个队列、树、图等结构来组织数据。同种结构的不同实例,也
许只在数据元素的类型或数量上略有差异,如果对每个实例都重新定义,则非常麻
烦且容易出错。那么能否对同种类型数据结构仅定义一次呢?答案是肯定的,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[I];
}
在这里,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)、置空(SetEmpty)、判断当前状态(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(); //将堆栈置空
无论我们使用哪种堆栈类,对用户来讲都是透明的,操作起来并无差别。

CList类的两个参数什么意思啊?第一个参数表示链表中存储的数据类型,后面一个表示链表类中函数参数的传递方式,通常为存储数据类型的引用。
CList<string,string> MyList_x;
CList<string,string&>MyList_y;
//两种方式实现的功能一样,不过后面一个更加高效。
CList <int,string> list;声明方式就是错误,
CList <int,int>list1;CList <int,char>list2;CList<char,int> list3;都是可以接受的声明方式。

MFC 的CList,CPtrList,CObList,CStringList 的用法之CList相关推荐

  1. MFC 的CList,CPtrList,CObList,CStringList 的用法

    一直在编程中使用stl进行编程,但是最近感觉微软提供的模版类也是很好,出错机率更低,建议在mfc的工程使用.相关介绍如下,参照msdn搞清接口即可使用 CList是通用型的列表类,你可以存放指定的数据 ...

  2. MFC中Create()函数的用法

    Create是一个可从CFrameWnd继承而来的成员函数,用于窗口的创建和设置. Create是MFC中的一个构造函数,用于生成在屏幕上可见的窗口. 示例如下: Create(NULL,_T(&qu ...

  3. MFC组合框控件总结及用法示例

    Combo Box (组合框)控件很简单,可以节省空间.从用户角度来看,这个控件是由一个文本输入控件和一个下拉菜单组成的.用户可以从一个预先定义的列表里选择一个选项,同时也可以直接在文本框里面输入文本 ...

  4. MFC中选项卡TabControl控件的用法

    前言:我这里的开发环境是VS2010,其它不同的开发环境可能会有所差别,但绝不会差太多,其根本方法一般是不会变的. 选项卡控件(英文名:TabControl),这个控件使用在开发一些比较复杂,和用户交 ...

  5. Visul C++中CList用法

    Visul C++中CList用法 MFC 的CList,CPtrList,CObList,CStringList ,使用方法相类似. 初学mfc者,往往对CList等mfc的Collect类的使用感 ...

  6. MFC CList使用

    转自:http://blog.sina.com.cn/s/blog_5cda82f40100aw58.html 一.类的概要和头文件 1. CList类:产生不定类型的列表,是一个集合类,也是一个双向 ...

  7. VC中CList用法

    初学mfc者,往往对CList等mfc的Collect类的使用感到迷惑,在使用中经常会遇到许多问题,导致对vc中的Collect类的使用产生了惧怕.以下,就个人经历而言,告诉大家如何使用CList. ...

  8. MFC链表CList类

    一.类的概要和头文件 1. CList类:产生不定类型的列表,是一个集合类,也是一个双向链表类,是一个类模板. 2. #include "Afxtempl.h"   //包含头文件 ...

  9. MFC VS2012 会员管理器(序列化和反序列化)

    上回老师又布置了一个作业,用MFC实现类的序列化功能,于是乎我就滚去摸索mfc的序列化,经过两三周的时间,终于把这个会员管理器搭得差不多了,主要的功能均已实现,算是半成品吧,因为还有一个小问题没解决( ...

最新文章

  1. pandas语法乱、API多?你需要整理一下!|知乎讨论
  2. plaxis 2d 2020中文版
  3. 加载svr模型_机器学习XGBoost实战,网格搜索自动调参,对比随机森林,线性回归,SVR【完整代码(含注释)+数据集见原文链接】...
  4. 文献学习(part80-B)--Do we Need Hundreds of Classifiers to Solve Real World Classification Problems?
  5. MySQL 的 Web 界面、前端或 GUI 工具
  6. C语言从入门到精通——初阶1 初识C语言
  7. 机甲大师s1 python编程_机甲大师RoboMaster S1教育机器人- DJI 大疆创新
  8. windows无法访问共享文件 所有解决方法(非复制粘贴的烂大街处理方法)
  9. gerrit rebase
  10. python 期货现货差价监测_火币网现货API[Python3版]
  11. 深度学习之 imgaug (图像增强)学习笔记
  12. JavaSE基础之(十六)final关键字
  13. 怎样用计算机求立方根的近似数,第三讲·立方根
  14. 【洛谷P2357】守墓人【线段树】
  15. 学习vb知识的方法总结
  16. 重返月球,铺路火星:2024年首位女性登月,280亿美元开启太空探索新纪元-1
  17. 如何解决E680i经常有内存不足提示的问题
  18. 手写口风琴全动态左侧导航栏
  19. 【SQL开发实战技巧】系列(十):从拆分字符串、替换字符串以及统计字符串出现次数说起
  20. 《你不可不知道的法律常识》读书摘记

热门文章

  1. 把网页保存成markdowm的方法
  2. 大数据处理的基本思路
  3. 单片机时钟周期、状态周期、机器周期、指令周期的理解
  4. webrtc服务器压测工具使用
  5. 机器学习与深度学习常见面试题(上)
  6. Android 实现一个计时器
  7. 基础算法--背包问题(01背包问题、完全背包问题、多重背包问题、分组背包问题)
  8. 背包问题——01背包
  9. DHCP 服务原理与配置
  10. 利用Matlab将图片转换成素描(简笔画)风格