以前在codeproject上看到過一篇關于內(nèi)存池的文章(http://www.codeproject.com/KB/cpp/MemoryPool.aspx)
下載下來試了試,感覺有點問題
想給引擎加入內(nèi)存池,考慮到當前業(yè)余時間在看Loki
就索性使用其SmallObject了
對于內(nèi)存池當然要求之一那就是速度
其次對我來說我比較關系以下的這類問題
一句話概括就是
Base* ptr = new SubClass;
索性我就根據(jù)Loki庫和Boost的Object_Pool
設計了如下的引擎內(nèi)存池(當然問題還很多以后慢慢修改)
#ifdef LOKI_EXT_LIB
#include <GEngine/Loki/Loki.hpp>
#else
#error 需要包含Loki庫
#endif
namespace core
{
////////////////////////////////////////////////////////////
/// 定義蓋莫引擎2.1.2內(nèi)存池對象
////////////////////////////////////////////////////////////
struct MemoryPool
{
public:
////////////////////////////////////////////////////////
/// 獲取,釋放指定大小的內(nèi)存
////////////////////////////////////////////////////////
template<class T>
static T* Malloc(size_t size)
{
return (T*)MEMORY_POOL.Allocate(size,false);
}
template<class T>
static void Free(T* ptr,size_t size)
{
MEMORY_POOL.Deallocate(ptr,size);
}
////////////////////////////////////////////////////////
/// 構(gòu)造無參數(shù)的對象類型并返回指針
////////////////////////////////////////////////////////
template<class T>
static T* Construct()
{
void* ptr = MEMORY_POOL.Allocate(OBJECT_SIZE(T),false);
if(ptr == NULL)
return NULL;
new(ptr)T();
return (T*)ptr;
}
////////////////////////////////////////////////////////
/// 構(gòu)造帶有1個參數(shù)的對象類型并返回指針
////////////////////////////////////////////////////////
template<class T,class P1>
static T* Construct(const P1 &p1)
{
void* ptr = MEMORY_POOL.Allocate(OBJECT_SIZE(T),false);
if(ptr == NULL)
return NULL;
new(ptr)T(p1);
return (T*)ptr;
}
////////////////////////////////////////////////////////
/// 構(gòu)造帶有2個參數(shù)的對象類型并返回指針
////////////////////////////////////////////////////////
template<class T,class P1,class P2>
static T* Construct(const P1 &p1,const P2 &p2)
{
void* ptr = MEMORY_POOL.Allocate(OBJECT_SIZE(T),false);
if(ptr == NULL)
return NULL;
new(ptr)T(p1,p2);
return (T*)ptr;
}
////////////////////////////////////////////////////////
/// 構(gòu)造帶有3個參數(shù)的對象類型并返回指針
////////////////////////////////////////////////////////
template<class T,class P1,class P2,class P3>
static T* Construct(const P1 &p1,const P2 &p2,const P3 &p3)
{
void* ptr = MEMORY_POOL.Allocate(OBJECT_SIZE(T),false);
if(ptr == NULL)
return NULL;
new(ptr)T(p1,p2,p3);
return (T*)ptr;
}
////////////////////////////////////////////////////////
/// 構(gòu)造帶有4個參數(shù)的對象類型并返回指針
////////////////////////////////////////////////////////
template<class T,class P1,class P2,class P3,class P4>
static T* Construct(const P1 &p1,const P2 &p2,const P3 &p3,const P4 &p4)
{
void* ptr = MEMORY_POOL.Allocate(OBJECT_SIZE(T),false);
if(ptr == NULL)
return NULL;
new(ptr)T(p1,p2,p3,p4);
return (T*)ptr;
}
////////////////////////////////////////////////////////
/// 構(gòu)造帶有5個參數(shù)的對象類型并返回指針
////////////////////////////////////////////////////////
template<class T,class P1,class P2,class P3,class P4,class P5>
static T* Construct(const P1 &p1,const P2 &p2,const P3 &p3,const P4 &p4,const P5 &p5)
{
void* ptr = MEMORY_POOL.Allocate(OBJECT_SIZE(T),false);
if(ptr == NULL)
return NULL;
new(ptr)T(p1,p2,p3,p4,p5);
return (T*)ptr;
}
////////////////////////////////////////////////////////
/// 給定對象的析構(gòu)(size為對象大小)
////////////////////////////////////////////////////////
template<class T>
static void Destruct(T* ptr, size_t size)
{
if(ptr == NULL || size <= 0)
return;
ptr->~T();
MEMORY_POOL.Deallocate(ptr,size);
}
////////////////////////////////////////////////////////
/// 獲取可分配的最大對象大小
////////////////////////////////////////////////////////
static int GetMaxObjSize()
{
return MEMORY_POOL.GetMaxObjectSize();
}
////////////////////////////////////////////////////////
/// 獲取字節(jié)對齊字節(jié)數(shù)
////////////////////////////////////////////////////////
static int GetAlignment()
{
return MEMORY_POOL.GetAlignment();
}
};
靜態(tài)的Malloc和Free是分配和釋放原生態(tài)的內(nèi)存
而Construct,Destruct則是構(gòu)造和析構(gòu)對象形式的內(nèi)存
這里提供了6個版本的Construct函數(shù)
分別對應0-5個構(gòu)造函數(shù)參數(shù)
記得以前遇到的一個問題
那就是假如有一個對象 她沒有默認構(gòu)造函數(shù)(只有帶參數(shù)構(gòu)造函數(shù))
如果現(xiàn)在需要分配N個她該如何操作?
那就是placement new 了