這也參照對象池的設計思想,隊列實際上就是一個對象池
但是隊列沒有對象池的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