阐释 MFC 集合类--链表类型篇

围绕微软提供的collect示例代码进行说明。可在X:/Microsoft Visual Studio 9.0/Samples/2052/C++/MFC/advanced/collect下找到该程序。

 

首先说说collect的框架。collect是一个SDI风格的窗口程序,“Example”菜单提供了9种不同的集合类示例,点击某一个集合类,可以切换到该集合类的视图窗口下,其中每个集合类都包括这些操作:

  • 添加新元素。

  • 将新元素插入到列表中间。

  • 搜索元素(通过在对话框的列表框中单击该元素的项)。

  • 通过输入搜索词并单击“Find”在映射中搜索项。

  • 更新元素的值。

  • 移除元素。

  • 移除集合中的所有元素。

  • 串行化(通过在“文件”菜单上单击“保存”可以保存对所有示例的更改,通过在“文件”菜单上单击“打开”则可以读回它们。)

  •  

    在类视图中,将9种集合类的视图分别绑定一个类(派生于CFormView),数据处理统统放在CCollectDoc类中。

     

    通过以上操作的学习,可以对集合类有个深入的了解。

     

    collect阐述了标志*号的集合类。

     

     

    集合形状

    非基于模板的

    基于模板的简单元素

    基于模板的 typeSafe 指针

    列表

    CStringList*

    CList*

    CTypedPtrList

     

    CObList

     

    (属于指针)*

     

    CPtrList

     

    CTypedPtrList

     

     

     

    (属于 CObject

    数组

    CByteArray

    CArray*

    CTypedPtrArray

     

    CUIntArray

     

    (属于指针)

     

    CWordArray

     

     

     

    CDWordArray *

     

    CTypedPtrArray

     

    CStringArray

     

    (属于 CObject)*

     

    CPtrArray

     

     

     

    CObArray

     

     

    映射

    CMapWordToPtr

    CMap*

    CTypedPtrMap*

     

    CMapWordToOb

     

     

     

    CMapStringToString*

     

     

     

    CMapStringToPtr

     

     

     

    CMapStringToOb

     

     

     

    CMapPtrToWord

     

     

     

    CMapPtrToPtr

     

     

    对于上表中,集合类还可以分为三个类型

    1、非基于模板的:又叫具体类,就是MFC已经预置了元素类型,不需要自定义。

    2、 基于模板的简单元素:又叫模板类,需要自己定义元素类型,元素的类型为对象实体。

    3、基于模板的 typeSafe 指针:带有typesafe特性,元素类型为自己指定的类对象指针。

    注:typesafe特性就是“Provides a type-safe "wrapper"”
    意指提供一个类型安全的“包装”
    因为定义时需要明确指出指针的类型,所以只能存储该类型的指针,不会有其它乱七八糟的指针存储进去。而很多指针类型的容器是允许保存任何类型的指针,常用void* 。

     

    这篇主要说说数组类型。

    先说说CStringList.

    CStringList集合中的元素类型为CString,可以理解为以CString元素组成的链表。

    它的操作包括:

    1、AddTail:在链表的尾部添加元素。

    2、InsertBefore:在指定的索引位置前插入元素。

    3、SetAt:在指定的索引位置设置指定的元素。

    4、RemoveAt:删除指定的索引位置的元素。

    5、RemoveAll:清除集合中所有的元素。

    6、串行化:可直接调用CStringList的Serialize进行串行化操作。

    7、Find或FindIndex:通过元素值或元素索引来搜索元素。返回POSITION类型。

    以上操作全部在CCollectDoc中处理。

     

    collect中还牵涉到一些控件的操作,包括列表框、编辑框、按钮。以下一一说明。这些说明对后面的几个类也同样适用。

    以CStringList的视图为例:
    1、编辑框IDC_ELEMENT绑定了成员函数m_strElement,以方便元素录入。

    2、列表框IDC_LIST绑定了成员函数m_ctlList,以方便控件操作。

    3、各按钮为集合操作定义

    看一个例子:

    void CStringListView::OnAdd()
    {
     if (UpdateData() != TRUE)
      return;

     GetDocument()->m_stringList.AddTail(m_strElement);
     m_ctlList.AddString(m_strElement);
    }

    这是添加元素按钮的响应函数。

    1、UpdateData() :默认的参数是TRUE,作用是将编辑框输入的值,更新到m_strElement中。如参数为FALSE,则是将m_strElement的值更新到编辑框上,在OnSelChangeList()函数中用到

    2、GetDocument():取得CCollectDoc的指针。

    3、m_stringList.AddTail():插入m_strElement到m_stringList集合末尾。

    4、m_ctlList.AddString():插入m_strElement到列表框中。

     

    再说说其他的列表框操作:
    1、m_ctlList.GetCurSel():取得当前在列表框中选择的元素的位置。若列表框为空或未选择,返回LB_ERR。

    2、m_ctlList.GetText():取得参数1索引的元素,存入参数2中,并将索引位置设定为下一个位置。

    3、m_ctlList.InsertString():在参数1指定的位置前插入参数2。

    4、m_ctlList.DeleteString():删除参数1索引指定的元素。返回剩余元素的数量int。

    5、m_ctlList.ResetContent():删除列表框中所有的元素。

     

     

    下面说说CTypedPtrList集合类。

    这个类在示例中用于存储类对象的指针。原型为:

    template< class BASE_CLASS, class TYPE >
    class CTypedPtrList : public BASE_CLASS

    其中 BASE_CLASS只能为CObList or CPtrList,class TYPE为类对象的指针。

     

    collect示例中,使用CTypedPtrListView类(继承于CFormView)显示此类的视图,数据处理全部放在CCollectDoc中。

    CCollectDoc中的定义:CTypedPtrList<CPtrList, CMyStruct*>

    此例中首先定义了CMyStruct类(无基类),有三个成员函数int,float,CString。

    然后需要将CMyStruct类对象的指针(CMyStruct*)存储到CTypedPtrList中。

    最后做相关操作。

    相关操作主要有:

    1、AddTail:向链表末尾添加元素。此处需要new一个CMyStruct对象,后期remove操作时,需delete这个对象。

    2、InsertBefore:在指定的索引位置前插入元素。

    3、RemoveAt:删除指定的索引位置的元素。

    4、RemoveAll:清除集合中所有的元素。

    5、Find:Find或FindIndex:通过元素值或元素索引来搜索元素。返回POSITION类型。

    注意:移除操作除了将集合类中将指针移除,同时也要用delete对CMyStruct对象进行释放。

    如下代码演示了这个过程:

     POSITION pos = mystructList.GetHeadPosition();//获取集合类中的第一个元素位置
     while (pos != NULL)
     {
      delete mystructList.GetNext(pos);//循环取出元素进行释放(注意这时释放的是指针指向的区域,而非指针本身
     }
     mystructList.RemoveAll();//移除存放在集合类中的指针(释放的是指针本身)

     

    最后说说CList

    这个类在一个模板类,示例中被定义为CList<int,int> m_intList,也就是一个int类型元素的集合。

    第一个参数表示链表中节点的数据类型为int,第二个参数表示操作时,传递给链表的参数类型必须为int。

    几个操作与CStringList一致。

     

     

    说了三个集合类,做一个阶段性的总结。

    首先以上阐述的三个类,都是以链表的形式实现的,也就是说,他们在做插入和删除元素时,比较高效。

    但在随机访问数据的能力上,链表需通过Find函数搜索元素位置,而后面要阐述的数组则直接通过下标访问,数组速度更快。

    三个类的基本操作类似,CTypedPtrList略微复杂,因链表中存储的是指针,在替换元素时,直接利用指针操作;在清除元素时,应注意释放指针本体和指针指向的区域。

     

    下一章进入数组类型集合类的阐述。

    你可能感兴趣的:(delete,存储,Class,mfc,float,wrapper)