代码
ObjectPool.hpp
#pragma once
#include <memory>
#include <queue>
#include <vector>
#include <cassert>
template< typename T >
class ObjectPool
{
public:
//初始化块大小如果能预先估算出块大小则性能达到最大
explicit ObjectPool( int AllSize = 64 );
virtual ~ObjectPool();
//模拟new关键字,取内存 并调用 T的构造函数
T* New();
//模拟delete关键字,归还内存 并调用 T的析构函数
void Delete( T *pT );
private:
// 扩容
void ExpandChunkSize();
//分配内存块 大小
void AllocateChunk( int ChunkSize );
//释放内存块
void ReleaseChunk();
private:
//空闲池
std::queue< T* > mFreePool;
//分配的所有 内存块 地址,包括扩展的
std::vector< T* > mAllPool;
//所有内存块 大小 , 多少个 类型 T 的大小
int mAllSize;
};
template< typename T >
ObjectPool< T >::ObjectPool( int AllSize )
:mAllSize(AllSize )
{
AllocateChunk(mAllSize);
}
template< typename T >
ObjectPool< T >::~ObjectPool()
{
ReleaseChunk();
}
template< typename T >
void ObjectPool< T >::ExpandChunkSize( )
{
int expand = mAllSize / 2;
mAllSize = mAllSize + expand;
if( !mFreePool.empty() ) // 不为空 不扩
{
return;
}
printf( "ExpandChunkSize() %d\n", expand );
AllocateChunk( expand );
}
template< typename T >
T* ObjectPool< T >::New()
{
if( mFreePool.empty() )
{
ExpandChunkSize();
}
if( mFreePool.empty() )
{
assert( false );
return nullptr;
}
T* pT = mFreePool.front();
mFreePool.pop();
// placement new 参见 https://blog.csdn.net/jiang4357291/article/details/104547867
new( pT )T();
return pT;
}
template< typename T >
void ObjectPool< T >::Delete( T *pT )
{
if( nullptr == pT )
{
assert( false );
return;
}
pT->~T();
mFreePool.push( pT );
}
template< typename T >
void ObjectPool< T >::AllocateChunk( int ChunkSize )
{
if( 0 == ChunkSize )
{
assert( false );
return;
}
T* pT = reinterpret_cast< T* >( malloc( ChunkSize * sizeof( T ) ) );
if( nullptr == pT )
{
assert( false );
return;
}
for( int i = 0; i < ChunkSize; ++i )
{
mFreePool.push( pT + i );
}
mAllPool.push_back(pT );
}
template< typename T >
void ObjectPool< T >::ReleaseChunk()
{
for(int i = 0; i < mAllPool.size(); ++i )
{
auto p = mAllPool[ i ];
printf( "ReleaseChunk() %p\n", p );
free( p );
mAllPool[ i ] = nullptr;
}
mAllPool.clear();
}
main.cpp 测试
#include <iostream>
#include "ObjectPool.hpp"
class Test
{
public:
Test()
{
printf( "Test() %p\n", this );
}
~Test()
{
printf( "~Test() %p\n", this );
}
void DoSomething()
{
printf( "DoSomething() %p\n", this );
}
};
int main()
{
/// 测试 // placement new 参见 https://blog.csdn.net/jiang4357291/article/details/104547867
Test* t=(Test*)malloc(sizeof(Test));
Test *p = new(t)Test();
printf( "Test* t = %p \n",t );
printf( "Test* p = %p \n",p );
t->~Test();
free(t);
printf( "Test ObjectPool Start...... \n" );
printf( "创建大小为2 Test类型大小 的对象池 \n" );
auto *objectPool = new ObjectPool< Test >(2);
printf( "测试New2个对象再Delete \n" );
Test *pTest1 = objectPool->New();
Test *pTest2 = objectPool->New();
pTest1->DoSomething();
pTest2->DoSomething();
objectPool->Delete( pTest1 );
objectPool->Delete( pTest2 );
printf( "再次New2个对象再Delete,并比较两次地址 \n" );
pTest1 = objectPool->New();
pTest2 = objectPool->New();
pTest1->DoSomething();
pTest2->DoSomething();
objectPool->Delete( pTest1 );
objectPool->Delete( pTest2 );
printf( "测试New4个对象再Delete,注意是否 扩展 \n" );
pTest1 = objectPool->New();
pTest2 = objectPool->New();
Test *pTest3 = objectPool->New();
Test *pTest4 = objectPool->New();
pTest1->DoSomething();
pTest2->DoSomething();
pTest3->DoSomething();
pTest4->DoSomething();
objectPool->Delete( pTest1 );
objectPool->Delete( pTest2 );
objectPool->Delete( pTest3 );
objectPool->Delete( pTest4 );
printf( "删除对象池 \n" );
delete(objectPool);
return 0;
}
new( pT )T() 用法 参见 https://blog.csdn.net/jiang4357291/article/details/104547867 中 placement new
测试结果
希望我的文章对于大家有帮助,由于个人能力的局限性,文中可能存在一些问题,欢迎指正、补充!