这也参照对象池的设计思想,队列实际上就是一个对象池
但是队列没有对象池的malloc,free,只有PushObj,PopObj
m_Used列表只能先进先出,不能随机访问,不能遍历
它具有和对象池一模一样的分配子TObjectAllocator,队列结点由Allocator动态分配
直接上代码
TObjectQueue.h
#ifndef _TObjectQueue_h_
#define _TObjectQueue_h_
#include <windows.h>
#include "TBDLinkList.h"
#include "TTree.h"
#include "TObjectAllocator.h"
#include "CLock.h"
#include "tool.h"
//自增队列
//
//该队列自行申请对象所需内存空间
//其实也是一个Pool(FIFO,不可以随机访问的池)
template <class T>
class TObjectQueue
{
public:
TObjectQueue();
~TObjectQueue();
//初始化函数
//dwFirstObjCount: 队列初始分配对象个数,不允许为0
//dwAddObjCount: Obj不够时,新增分配Obj个数,
// 允许传0,表示不够时不开辟新内存,返回空
//dwLock: 设置是否使用临界区
// 初始默认为Enable,即使用临界区
public:
bool Init(DWORD dwFirstObjCount,
DWORD dwAddObjCount,
ContainerFlag dwLock = enum_EnableLock);
//释放队列的所有分配子
public:
void Release();
//向队列增加一个Obj
//obj: 传入参数,需要放入队列的Obj
// 队列会自行分配空间拷贝Obj信息
// 不需要调用者保存传入的Obj
//成功返回true
//队列已满返回false
public:
bool PushObj(T& obj);
//从队列取出一个Obj(移除)
//obj: 传出参数,放置取出的Obj信息
//成功返回true
//队列已空返回false
public:
bool PopObj(T& obj);
//队列长度不够时,增加分配子,开辟新内存
private:
bool AddObject(DWORD dwAddCount);
//获取当前各个列表使用情况
public:
DWORD GetUsedListLen();
DWORD GetFreeListLen();
private:
TBDLinkList<T> m_Used;//使用中的Obj列表
TBDLinkList<T> m_Free;//空闲Obj列表
TBDLinkList<TObjectAllocator<T>> m_MemAllocList;//Obj对象池分配子管理链表
DWORD m_dwAddObjCount;
};
#include "TObjectQueue.hpp"
#endif
TObjectQueue.hpp
#ifndef _TObjectQueue_hpp_
#define _TObjectQueue_hpp_
template <class T>
TObjectQueue<T>::TObjectQueue()
{
m_Used.Init(enum_DisableLock);
m_Free.Init(enum_DisableLock);
m_MemAllocList.Init(enum_DisableLock);
m_dwAddObjCount = 0;
}
template <class T>
TObjectQueue<T>::~TObjectQueue()
{
Release();
}
template <class T>
bool TObjectQueue<T>::Init(DWORD dwFirstObjCount, DWORD dwAddObjCount, ContainerFlag dwLock)
{
if (0 == dwFirstObjCount)
{
//初始化参数不正确
return false;
}
else
{
m_dwAddObjCount = dwAddObjCount;
m_Used.Init(dwLock);
m_Free.Init(dwLock);
m_MemAllocList.Init(dwLock);
//申请分配子,开辟第一块内存
return AddObject(dwFirstObjCount);
}
}
template <class T>
void TObjectQueue<T>::Release()
{
m_Used.Init(enum_DisableLock);
m_Free.Init(enum_DisableLock);
TBDLinker<TObjectAllocator<T>> *pLinker = m_MemAllocList.PopHead();
while (NULL != pLinker)
{
delete pLinker;
pLinker = m_MemAllocList.PopHead();
}
m_MemAllocList.Init(enum_DisableLock);
m_dwAddObjCount = 0;
}
template <class T>
bool TObjectQueue<T>::PushObj(T& obj)
{
TBDLinker<T> *pLinker = m_Free.PopHead();
if (NULL == pLinker)
{
if (AddObject(m_dwAddObjCount))
{
pLinker = m_Free.PopHead();
}
}
if (NULL == pLinker)
{
return false;
}
else
{
memcpy(&(pLinker->m_Value), &obj, sizeof(T));
return m_Used.PushTail(pLinker);
}
}
template <class T>
bool TObjectQueue<T>::PopObj(T& obj)
{
TBDLinker<T> *pLinker = m_Used.PopHead();
if (NULL == pLinker)
{
return false;
}
else
{
memcpy(&obj, &(pLinker->m_Value), sizeof(T));
return m_Free.PushTail(pLinker);
}
}
template <class T>
bool TObjectQueue<T>::AddObject(DWORD dwAddCount)
{
if (0 == dwAddCount)
{
return false;
}
else
{
TBDLinker<TObjectAllocator<T>> *pAllocLinker = new TBDLinker<TObjectAllocator<T>>;
if (NULL == pAllocLinker)
{
return false;
}
pAllocLinker->Init();
if (!pAllocLinker->m_Value.Init(dwAddCount, m_Free))
{
delete pAllocLinker;
return false;
}
m_MemAllocList.PushTail(pAllocLinker);
return true;
}
}
template <class T>
DWORD TObjectQueue<T>::GetUsedListLen()
{
return m_Used.GetLen();
}
template <class T>
DWORD TObjectQueue<T>::GetFreeListLen()
{
return m_Free.GetLen();
}
#endif