对象池模板类:
#pragma once
#include "CObjInstance.h"
#include <mutex>
#include <vector>
#include <map>
/// <summary>
/// 实现模板类型对象池,使其可以适配任何类类型且是线程安全的!!!
/// </summary>
template<class T>
class CObjPool
{
public:
CObjPool() {}
~CObjPool()
{
if (m_poolMemoryHeader)
{
//先释放对象内存
while (m_pRootNode)
{
delete (T*)(m_pRootNode->pObjInstance);
m_pRootNode = m_pRootNode->pNext;
}
//再释放node的内存
delete[] m_poolMemoryHeader;
m_poolMemoryHeader = nullptr;
}
}
/// <summary>
/// 每个对象的头节点
/// </summary>
struct HeadNode
{
char* pObjInstance; //obj实例指针
HeadNode* pNext; //下一个obj实例指针
size_t nRefCount; //obj引用次数
size_t nID; //obj的ID
};
/// <summary>
/// 获取对象池的对象数
/// </summary>
/// <returns></returns>
int GetPoolSetObjCount()
{
return m_poolObjCount;
}
/// <summary>
//初始化对象池
/// </summary>
template<typename... Args>
void InitObjPool(int nObjCount, Args... args)
{
if (nObjCount <= 0)
{
return;
}
//初始化使用内存
size_t nUseMemorySize = nObjCount * (sizeof(HeadNode)); //一次性分配内存池对象需要使用的总内存(对象自己的内存除外)
m_poolMemoryHeader = new char[nUseMemorySize];
memset(m_poolMemoryHeader, 0, nUseMemorySize * sizeof(char));
//初始化跟节点
char* tempMemoryHeader = m_poolMemoryHeader;
m_pRootNode = InitHeadNode(tempMemoryHeader);
tempMemoryHeader = tempMemoryHeader + (sizeof(HeadNode));
m_pRootNode->nID = 1;
m_pRootNode->pObjInstance = (char*)(new T(args...));
//tempMemoryHeader += sizeof(T);
m_mapFreeNode[m_pRootNode->nID] = m_pRootNode;
//初始化其它节点
HeadNode* tempNode = m_pRootNode;
for (int i = 1; i < nObjCount; i++)
{
HeadNode* node = InitHeadNode(tempMemoryHeader);
tempMemoryHeader = tempMemoryHeader + (sizeof(HeadNode));
node->pObjInstance = (char*)(new T(args...));
node->nID = tempNode->nID + 1;
m_mapFreeNode[node->nID] = node;
//tempMemoryHeader += sizeof(T);
tempNode->pNext = node;
tempNode = node;
}
m_poolObjCount = nObjCount;
}
//获取使用对象
T* NewObjInstance()
{
std::lock_guard<std::mutex> lg(m_mutex);
//从对象池中取可用的对象,若无可用返回空
T* obj = nullptr;
if (m_mapFreeNode.empty())
{
return obj;
}
HeadNode* node = (*m_mapFreeNode.begin()).second;
obj = (T*)(node->pObjInstance);
node->nRefCount++;
m_mapFreeNode.erase(m_mapFreeNode.begin());
return obj;
}
//释放使用对象
void DeleteObjInstance(void* p)
{
HeadNode* node = m_pRootNode;
while (node)
{
if (node->pObjInstance == p)
{
break;
}
node = node->pNext;
}
if (node == nullptr)
{
return;
}
node->nRefCount--;
if (node->nRefCount == 0)
{
std::lock_guard<std::mutex> lg(m_mutex);
m_mapFreeNode[node->nID] = node;
}
}
private:
//初始化HeadNode
HeadNode* InitHeadNode(char* p)
{
HeadNode* node = (HeadNode*)p;
node->nRefCount = 0;
node->pNext = nullptr;
node->nID = 0;
return node;
}
private:
int m_poolObjCount = 0; //对象池中的对象总数
char* m_poolMemoryHeader = nullptr; //对象池内存起始地址
HeadNode* m_pRootNode = nullptr; //对象池根节点
std::map<size_t, HeadNode*> m_mapFreeNode; //空闲obj节点 key:节点ID value: 节点指针
std::mutex m_mutex; //申请obj锁
};
测试代码:
```cpp
#include <iostream>
#include "CObjPool.h"
class A
{
public:
A(int n)
{
a = n;
}
~A()
{
std::cout << "~A" << std::endl;
}
public:
int a = 0;
};
class B
{
public:
B(int n, int m)
{
a = n;
b = m;
}
~B()
{
std::cout << "~B" << std::endl;
}
public:
int a = 0;
int b = 0;
};
void Test()
{
CObjPool<A>* poolA = new CObjPool<A>();
poolA->InitObjPool(10, 6);
A* a1 = poolA->NewObjInstance();
a1->a = 1;
A* a2 = poolA->NewObjInstance();
a2->a = 2;
A* a3 = poolA->NewObjInstance();
poolA->DeleteObjInstance(a1);
poolA->DeleteObjInstance((char*)a2);
a3 = poolA->NewObjInstance();
a3->a = 3;
poolA->DeleteObjInstance(a3);
delete poolA;
poolA = nullptr;
CObjPool<B>* poolB = new CObjPool<B>();
poolB->InitObjPool(10, 6, 9);
B* b1 = poolB->NewObjInstance();
std::cout << b1->a << b1->b << std::endl;
poolB->DeleteObjInstance(b1);
b1 = nullptr;
b1 = poolB->NewObjInstance();
b1->a = 3;
b1->b = 3;
std::cout << b1->a << b1->b << std::endl;
poolB->DeleteObjInstance(b1);
delete poolB;
poolB = nullptr;
}
int main()
{
Test();
std::cout << "Hello World!\n";
}
测试结果: