今天放上容器类的基类TContainer
1、以下4个接口需要子类实现
初始化\清空容器 virtual void Init(ContainerFlag dwLock) = 0;
获取该容器中第一个T对象 virtual T *GetHead() = 0;
获取该容器中curr的下一个T对象 virtual T *GetNext(T *curr) = 0;
获取链表中curr对应的管理结点对象 virtual void *GetNode(T *curr) = 0;
2、容器记录有一个m_IterList,保存所有在该容器上注册的迭代器
3、容器向所有子类提供一个接口:void ResetNext(T *next)
当容器remove一个对象时,需要调用该接口
检查所有注册的迭代器,判断remove的对象是否是下一个将要迭代的对象,是则将迭代器后移一个对象
4、将锁对象放到了基类中,提供给子类使用,统一初始化参数的枚举定义ContainerFlag
5、向迭代器提供4个接口:
(1)、向该容器注册一个迭代器void Register(TIterator<T> &iter);
(2)、向该容器取消注册一个迭代器void UnRegister(TIterator<T> &iter);
(3)、迭代器开始遍历bool BeginListBy(TIterator<T> &iter);
(4)、迭代器获取下一个对象bool GetNextBy(TIterator<T> &iter);
这4个接口私有,只提供给迭代器使用,迭代器通过友元关系访问
接下来的工作就是修改之前提供的链表跟二叉树,让其继承自TContainer
下面上代码
TContainer.h
#ifndef _TContainer_h_
#define _TContainer_h_
#include <windows.h>
#include "CList.h"
#include "TIterator.h"
#include "CLock.h"
#include "tool.h"
enum ContainerFlag
{
enum_EnableLock = 0, //容器是否开启临界区锁
enum_DisableLock,
};
template <class T>
class TContainer
{
friend class TIterator<T>;
public:
TContainer();
virtual ~TContainer();
//获取容器中对象的个数
DWORD GetLen();
//初始化\清空容器
virtual void Init(ContainerFlag dwLock) = 0;
//获取该容器中第一个T对象
virtual T *GetHead() = 0;
//获取该容器中curr的下一个T对象
virtual T *GetNext(T *curr) = 0;
//获取链表中curr对应的管理结点对象
virtual void *GetNode(T *curr) = 0;
protected:
//当next指向的对象所对应的管理结点被操作删除时
//检查注册在该容器上的所有迭代器
//若有迭代器下一个将要迭代的结点指针是next
//将下一个将要迭代的指针指针后移
//继承该基类的各个容器子类在移除某一对象之前
//需要调用该函数检查各迭代器的next指针是否需要后移
void ResetNext(T *next);
//容器中对象的个数
DWORD m_dwLen;
//是否使用临界区进行加锁
ContainerFlag m_dwLock;
//临界区,保证容器操作的线程安全
CLock m_csLock;
private:
//以下四个函数仅提供给Iterator使用:
//向该容器注册一个迭代器对象
//定义一个迭代器对象后
//需要将该迭代器注册给被迭代的容器
void Register(TIterator<T> &iter);
//向该容器取消注册一个迭代器对象
//迭代完成后
//需要将该迭代器从被迭代的容器中取消注册
//若该函数不手动调用
//在Iterator的析构时会自动调用
void UnRegister(TIterator<T> &iter);
//为迭代器iter准备遍历环境
//修改Next指针
//指向容器中的第一个节点
//成功返回true
//若容器中无结点
//将Next指针置空,返回true
//若迭代器iter未注册给本容器,则返回false
bool BeginListBy(TIterator<T> &iter);
//修改迭代器iter的Next指针
//指向下一个待遍历的结点
//成功返回true
//若迭代已经结束,没有下一个结点了
//将Next指针置空,返回true
//若迭代器iter未注册给本容器,则返回false
bool GetNextBy(TIterator<T> &iter);
//在该容器上注册的迭代器的列表
CList m_IterList;
};
#include "TContainer.hpp"
#endif
TContainer.hpp
#ifndef _TContainer_hpp_
#define _TContainer_hpp_
template <class T>
TContainer<T>::TContainer()
{
m_dwLen = 0;
m_dwLock = enum_DisableLock;
m_IterList.Init();
}
template <class T>
TContainer<T>::~TContainer()
{
Node *pNode = m_IterList.GetHead();
while(NULL != pNode)
{
TIterator<T> *pIter = TIterator<T>::GetIterator(pNode);
pIter->m_pContainer = NULL;
pNode = pNode->m_pNext;
}
m_dwLen = 0;
m_dwLock = enum_DisableLock;
m_IterList.Init();
}
template <class T>
DWORD TContainer<T>::GetLen()
{
return m_dwLen;
}
template <class T>
void TContainer<T>::ResetNext(T *next)
{
if (enum_EnableLock == m_dwLock)
{
m_csLock.Lock();
}
Node *pNode = m_IterList.GetHead();
while (NULL != pNode)
{
TIterator<T> *pIterater = TIterator<T>::GetIterator(pNode);
if (this == pIterater->m_pContainer)
{
if (next == pIterater->m_pNextPtr)
{
pIterater->m_pNextPtr = GetNext(pIterater->m_pNextPtr);
}
}
pNode = pNode->m_pNext;
}
if (enum_EnableLock == m_dwLock)
{
m_csLock.UnLock();
}
}
template <class T>
void TContainer<T>::Register(TIterator<T> &iter)
{
if (enum_EnableLock == m_dwLock)
{
m_csLock.Lock();
}
m_IterList.PushTail(iter.m_LinkNode);
iter.m_pContainer = this;
if (enum_EnableLock == m_dwLock)
{
m_csLock.UnLock();
}
}
template <class T>
void TContainer<T>::UnRegister(TIterator<T> &iter)
{
if (enum_EnableLock == m_dwLock)
{
m_csLock.Lock();
}
m_IterList.Remove(iter.m_LinkNode);
iter.m_pContainer = NULL;
if (enum_EnableLock == m_dwLock)
{
m_csLock.UnLock();
}
}
template <class T>
bool TContainer<T>::BeginListBy(TIterator<T> &iter)
{
bool bRes = true;
if (enum_EnableLock == m_dwLock)
{
m_csLock.Lock();
}
if (this == iter.m_pContainer)
{
iter.m_pNextPtr = GetHead();
bRes = true;
}
if (enum_EnableLock == m_dwLock)
{
m_csLock.UnLock();
}
return bRes;
}
template <class T>
bool TContainer<T>::GetNextBy(TIterator<T> &iter)
{
bool bRes = true;
if (enum_EnableLock == m_dwLock)
{
m_csLock.Lock();
}
if (this == iter.m_pContainer)
{
iter.m_pNextPtr = GetNext(iter.m_pNextPtr);
bRes = true;
}
if (enum_EnableLock == m_dwLock)
{
m_csLock.UnLock();
}
return bRes;
}
#endif