MFC中CList类使用方法
来源:互联网 发布:淘宝千里眼怎么样 编辑:程序博客网 时间:2024/04/26 20:51
CList是一个双向链表类。
1:Clist类定义在Afxtempl.h 头文件中,因此在使用该类时,需要加这个头文件名。
2、理解CList的声明和构造方法
CList的声明如下:
template< class TYPE, class ARG_TYPE >class CList : public CObject
CList<CPoint, CPoint&> list;
这样就指定了CList中存放的是CPoint类型的引用。
由此,我们知道CList是一个模版类,那么他的两个class是什么意思呢?
下面看一个例子:
CList<CString ,CString&> list;//链表对象1CList<CString,CString> list2;//链表对象2
这里的第一个参数CString是实例化的类型,第二个参数是类的成员函数的参数的调用形式,通常是类型 引用,当然也可以是对象,而不是引用。对象和引用的区别,可以看一下C++基础知识方面的书。
3、使用CList的迭代器
迭代器是近年在链表使用中的一个常用技术。如果大家学过java,就会知道,在java中,会有专门的一个迭代器类,这个迭代器类用来访问Collect中的数据元素。在mfc中,在CList中,定义了几个迭代器的函数。他们方便了我们去访问数据元素。
GetHeadPositionReturns the position of the head element of the list.GetTailPositionReturns the position of the tail element of the list.GetNextGets the next element for iterating.GetPrevGets the previous element for iterating.
以上是四个迭代器函数。前两个他们的返回值是POSITION,它是mfc中定义的的一种专门访问Collect类的一个数据类型。用他来表示元素的位置。
// abstract iteration positionstruct __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 herelist.Serialize(ar);}}
这样,就实现了文档的串行化,如果使用mfc生成的框架,那么我们就可以直接将这个list的数据保存到文件,并能读取了。
CList声明的原型
template<class TYPE, class ARG_TYPE = const TYPE&>class CList : public CObject{protected:struct CNode{CNode* pNext;// 后指针CNode* pPrev;// 前指针TYPE data;// 数据};public:// Construction/* explicit */ CList(INT_PTR nBlockSize = 10);// Attributes (head and tail)// count of elementsINT_PTR GetCount() const;// return m_nCount;INT_PTR GetSize() const;// return m_nCount;BOOL IsEmpty() const;// return m_nCount == 0;// peek at head or tailTYPE& GetHead();// return m_pNodeHead->data;const TYPE& GetHead() const;TYPE& GetTail();// return m_pNodeTail->data;const TYPE& GetTail() const;// Operations// get head or tail (and remove it) - don't call on empty list !TYPE RemoveHead();// 删除头部元素,并返回其元素值TYPE RemoveTail();// 删除尾部元素,并返回其元素值// add before head or after tailPOSITION AddHead(ARG_TYPE newElement);POSITION AddTail(ARG_TYPE newElement);// add another list of elements before head or after tailvoid AddHead(CList* pNewList);void AddTail(CList* pNewList);// remove all elementsvoid RemoveAll();// iterationPOSITION GetHeadPosition() const;// return (POSITION) m_pNodeHead;POSITION GetTailPosition() const;// return (POSITION) m_pNodeTail;TYPE& GetNext(POSITION& rPosition);// return *Position++const TYPE& GetNext(POSITION& rPosition) const; // return *Position++TYPE& GetPrev(POSITION& rPosition);// return *Position--const TYPE& GetPrev(POSITION& rPosition) const; // return *Position--// getting/modifying an element at a given positionTYPE& GetAt(POSITION position);const TYPE& GetAt(POSITION position) const;void SetAt(POSITION pos, ARG_TYPE newElement);void RemoveAt(POSITION position);// inserting before or after a given positionPOSITION InsertBefore(POSITION position, ARG_TYPE newElement);POSITION InsertAfter(POSITION position, ARG_TYPE newElement);// helper functions (note: O(n) speed)POSITION Find(ARG_TYPE searchValue, POSITION startAfter = NULL) const;// defaults to starting at the HEAD, return NULL if not foundPOSITION FindIndex(INT_PTR nIndex) const;// get the 'nIndex'th element (may return NULL)// Implementationprotected:CNode* m_pNodeHead;// 指向链表头的指针CNode* m_pNodeTail;// 指向链表尾的指针INT_PTR m_nCount;// 元素个数CNode* m_pNodeFree;// 空闲节点链表struct CPlex* m_pBlocks;// 数据块载体链表INT_PTR m_nBlockSize;// 每个数据块元素个数CNode* NewNode(CNode*, CNode*);// 创建新节点void FreeNode(CNode*);// 释放节点数据public:~CList();void Serialize(CArchive&);#ifdef _DEBUGvoid Dump(CDumpContext&) const;void AssertValid() const;#endif};
RemoveHead 和 FreeNode 函数
// 删除头部元素,并返回其元素值template<class TYPE, class ARG_TYPE>TYPE CList<TYPE, ARG_TYPE>::RemoveHead(){CNode* pOldNode = m_pNodeHead;TYPE returnValue = pOldNode->data;m_pNodeHead = pOldNode->pNext;if (m_pNodeHead != NULL)m_pNodeHead->pPrev = NULL;elsem_pNodeTail = NULL;FreeNode(pOldNode);return returnValue;}// 释放节点template<class TYPE, class ARG_TYPE>void CList<TYPE, ARG_TYPE>::FreeNode(CNode* pNode){pNode->data.~TYPE();pNode->pNext = m_pNodeFree;// 将节点加入空闲节点链表m_pNodeFree = pNode;m_nCount--;// if no more elements, cleanup completelyif (m_nCount == 0)RemoveAll();}AddHead(插入元素) 和 NewNode 函数
// 在链表头部插入值为newElement的元素template<class TYPE, class ARG_TYPE>POSITION CList<TYPE, ARG_TYPE>::AddHead(ARG_TYPE newElement){CNode* pNewNode = NewNode(NULL, m_pNodeHead);pNewNode->data = newElement;if (m_pNodeHead != NULL)m_pNodeHead->pPrev = pNewNode;elsem_pNodeTail = pNewNode;m_pNodeHead = pNewNode;return (POSITION) pNewNode;}// 创建一个新节点template<class TYPE, class ARG_TYPE>typename CList<TYPE, ARG_TYPE>::CNode*CList<TYPE, ARG_TYPE>::NewNode(CNode* pPrev, CNode* pNext){if (m_pNodeFree == NULL){// add another blockCPlex* pNewBlock = CPlex::Create(m_pBlocks, m_nBlockSize, sizeof(CNode));// chain them into free listCNode* pNode = (CNode*) pNewBlock->data();// free in reverse order to make it easier to debugpNode += m_nBlockSize - 1;for (INT_PTR i = m_nBlockSize-1; i >= 0; i--, pNode--){pNode->pNext = m_pNodeFree;m_pNodeFree = pNode;}}CList::CNode* pNode = m_pNodeFree;m_pNodeFree = m_pNodeFree->pNext;pNode->pPrev = pPrev;pNode->pNext = pNext;m_nCount++;::new( (void*)( &pNode->data ) ) TYPE;return pNode;}
AddHead函数(插入链表)
// 在链表头部插入pNewList所指链表 template<class TYPE, class ARG_TYPE> void CList<TYPE, ARG_TYPE>::AddHead(CList* pNewList) { // add a list of same elements to head (maintain order) POSITION pos = pNewList->GetTailPosition(); while (pos != NULL) AddHead(pNewList->GetPrev(pos)); }
RemoveAll函数
// 移除所有的元素 template<class TYPE, class ARG_TYPE> void CList<TYPE, ARG_TYPE>::RemoveAll() { // destroy elements CNode* pNode; for (pNode = m_pNodeHead; pNode != NULL; pNode = pNode->pNext) pNode->data.~TYPE(); m_nCount = 0; m_pNodeHead = m_pNodeTail = m_pNodeFree = NULL; m_pBlocks->FreeDataChain(); // 释放数据链 m_pBlocks = NULL; }
RemoveAt函数
// 移除指定位置的元素 template<class TYPE, class ARG_TYPE> void CList<TYPE, ARG_TYPE>::RemoveAt(POSITION position) { CNode* pOldNode = (CNode*) position; // remove pOldNode from list if (pOldNode == m_pNodeHead) m_pNodeHead = pOldNode->pNext; else pOldNode->pPrev->pNext = pOldNode->pNext; if (pOldNode == m_pNodeTail) m_pNodeTail = pOldNode->pPrev; else pOldNode->pNext->pPrev = pOldNode->pPrev; FreeNode(pOldNode); // 释放节点数据。 }
InsertBefore函数
// 在指定位置之前插入值为newElement的元素。 template<class TYPE, class ARG_TYPE> POSITION CList<TYPE, ARG_TYPE>::InsertBefore(POSITION position, ARG_TYPE newElement) { if (position == NULL) return AddHead(newElement); // insert before nothing -> head of the list // Insert it before position CNode* pOldNode = (CNode*) position; CNode* pNewNode = NewNode(pOldNode->pPrev, pOldNode); pNewNode->data = newElement; if (pOldNode->pPrev != NULL) pOldNode->pPrev->pNext = pNewNode; else m_pNodeHead = pNewNode; pOldNode->pPrev = pNewNode; return (POSITION) pNewNode; }
Find函数
// 从startAfter后开始查找值为searchVaule元素,返回位置 template<class TYPE, class ARG_TYPE> POSITION CList<TYPE, ARG_TYPE>::Find(ARG_TYPE searchValue, POSITION startAfter) const { CNode* pNode = (CNode*) startAfter; if (pNode == NULL) pNode = m_pNodeHead; // start at head else pNode = pNode->pNext; // start after the one specified for (; pNode != NULL; pNode = pNode->pNext) if (CompareElements<TYPE>(&pNode->data, &searchValue)) return (POSITION)pNode; return NULL; }
RemoveHead 和 FreeNode 函数
0 0
- MFC中CList类使用方法
- MFC中CList类使用注意
- MFC中CList类使用注意
- MFC中CList类使用注意
- MFC链表CList类
- MFC容器类CArray,CList
- MFC容器类CArray,CList
- MFC容器类CArray,CList
- MFC集合类之CList
- VC MFC中CList成员的使用
- 在使用MFC双向链表模板类CList中Find问题
- MFC CList使用
- MFC CList 遍历删除
- 【MFC】关于mfc中的Clist
- CList 类
- CList类
- 派生MFC模板类CList 增加排序功能
- MFC复习和学习 第七章 MFC调色板 MFC区域 MFC数据结合类 CArray CList
- 加载图片对象
- 文章标题
- DWR3+SPRING+HIBERNATE的有返回值的融合
- XML注入攻击
- Rust入门篇 &mut
- MFC中CList类使用方法
- Ubuntu16.04中MySQL安装配置
- 微信公众号开发_项目说明(一)
- 包引用冲突 Jackson : NoSuchMethodError for org.codehaus.jackson.map...
- React native 入门二 魅力展示
- Android禁止ViewPager左右滑动
- 双击返回键退出
- 大学应该教会学生什么?
- Leetcode 100 SameTree