1
.
Clist
的使用
初学
mfc
者,往往对
CList
等
mfc
的
Collect
类的使用感到迷惑,在使用中经常会遇到许多问题,导致对
vc
中的
Collect
类的使用产生了惧怕。以下,就个人经历而言
,
告诉大家如何使用
CList
。
CList
是一个双向链表类。
1
、头文件名不可少
Clist
类定义在
Afxtempl.h
头文件中,因此在使用该类时,需要加这个头文件名。
2
、理解
CList
的声明和构造方法
CList
的声明如下:
template< class
TYPE
, class
ARG_TYPE
>class CList : public CObject
由此,我们知道
CList
是一个模版类,那么他的两个
class
是什么意思呢?
下面看一个例子:
CList<CString ,CString&> list;//
链表对象
1
CList<CString,CString> list2;//
链表对象
2
这里的第一个参数
CString
是实例化的类型,第二个参数是类的成员函数的参数的调用形式,通常是类型 引用,当然也可以是对象,而不是引用。对象和引用的区别,可以看一下
C++
基础知识方面的书。
3
、使用
CList
的迭代器
迭代器是近年在链表使用中的一个常用技术。如果大家学过
java
,就会知道,在
java
中,会有专门的一个迭代器类,这个迭代器类用来访问
Collect
中的数据元素。在
mfc
中,在
CList
中,定义了几个迭代器的函数。他们方便了我们去访问数据元素。
GetHeadPosition
|
Returns the position of the head element of the list.
|
GetTailPosition
|
Returns the position of the tail element of the list.
|
GetNext
|
Gets the next element for iterating.
|
GetPrev
|
Gets the previous element for iterating.
|
以上是四个迭代器函数。前两个他们的返回值是
POSITION
,它是
mfc
中定义的的一种专门访问
Collect
类的一个数据类型。用他来表示元素的位置。
// abstract iteration position
struct __POSITION { };
typedef __POSITION* POSITION;
以上是在跟踪
POSITION
定义中找到的。由此,我们知道
POSITION
是个抽象的迭带器位置。至于怎么实现,我也只能知道这么多,如果有哪位高手知道的话,一定要告诉我们哦。
下面我们利用给出的迭代器函数,对下面建立的链表进行遍历:
CList<CString ,CString&> list;
CString str1="hello";
CString str2="world";
CString str3="my";
CString str4="life";
list.AddTail(str1);
list.AddTail(str2);
list.AddTail(str3);
list.AddTail(str4);
POSITION pos = list.GetHeadPosition();
while(pos!=NULL)
{
pDC->TextOut(200,200,GetNext( POSITION&
rPosition
) );//
假设代码是在
View
类中的
OnDraw()
//
函数里
}
这样就完成了对
list
的遍历。
4
、
CList
的其它函数:
CList
的其它函数,大家可以参考一下
MSDN
,在那里每个函数都讲得很清楚。这里就不再多介绍。
5
、
CList
的元素
对于系统定义的类,可以直接在
CList
中使用。而对于用户自定义的类,如果这个类继承了
CObject
类,在使用
CList
时,需要将用户自定义的类实现操作符
=
的重载,否则系统将会报错。以下举一简单的
CNode
例子,使之实现操作符
=
的重载:
class CNode : public CObject
{
public:
CPoint point;
CNode()
{
point.x=0;
point.y=0;
}
void operator = (CPoint& p)//
运算符
=
的重载
{
point=p;
}
};
6
、
CList
的序列化:
CList
是一个继承了
CObject
的类,并且已经实现了
Serialize(CArchive& ar)
的函数,所以,对
CList
进行串行序列化不需要的。
如果在
CList
类在
CDocument
定义了其对象
list
,那么在文档的
Serialize(CArchive& ar)
只需作如下修改:
void CDdfDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
// TODO: add storing code here
list.Serialize(ar);
}
else
{
// TODO: add loading code here
list.Serialize(ar);
}
}
这样,就实现了文档的串行化,如果使用
mfc
生成的框架,那么我们就可以直接将这个
list
的数据保存到文件,并能读取了。