|
|
????????????????k??????????????????????????????????????????????????????TObjectPool<T,k>: tr????k??????????????????????????????????k??????????????
#ifndef _TObjectPoolV12_H_
#define _TObjectPoolV12_H_
#include<iostream>
#pragma warning(disable: 4786)//??4786??(STL?????????255??)
#include<list>
#include<algorithm>
namespace Aura
{
//TObjectPool1.2
//???????????????????????????????????????????????
//????
enum TObjectPool_error
{
TObjectPool_error_no,
TObjectPool_error_memory, //??????
TObjectPool_error_null_pointer, //????
TObjectPool_error_multiple_return, //????
};
const static char* TObjectPool_error_strings_A[] = {
"??",
"??????",
"????",
"????"};
const static wchar_t* TObjectPool_error_strings_W[] = {
L"??",
L"??????",
L"????",
L"????"};
#ifdef UNICODE
#define TObjectPool_error_strings TObjectPool_error_strings_W
#else
#define TObjectPool_error_strings TObjectPool_error_strings_A
#endif
template <typename T>
class TObjectPool
{
private:
class page;
public:
//proxy classes
class Ptr
{
public:
friend class page;
Ptr():m_p(NULL){}
~Ptr(){}
T* operator->()const{return m_p;}
T& operator*()const{return *m_p;}
operator bool()const{return NULL!=m_p;}
private:
Ptr(T* p){}
Ptr(const Ptr& rhs){}
Ptr& operator=(const Ptr& rhs){}
T* m_p;
};
public:
TObjectPool(unsigned long per_page_object_count=16);
~TObjectPool();
//??????
bool operator >>(Ptr& ptr);
//??????(?????ptr?NULL?)?
bool operator <<(Ptr& ptr);
//??????
TObjectPool_error error()const{return m_error;}
private:
class page
{
public:
page(unsigned long k)
:m_object_count(k),m_objects(0),m_objects_statck(0),m_objects_idle_flag(0),m_memory_error(false)
{
if(NULL==(m_objects=new T[m_object_count])){set_memory_error();return;}
if(NULL==(m_objects_statck=new T*[m_object_count])){set_memory_error();return;}
if(NULL==(m_objects_idle_flag=new bool[m_object_count])){set_memory_error();return;}
for(m_statck_top=0; m_statck_top<m_object_count; ++m_statck_top)
{
m_objects_statck[m_statck_top]=&m_objects[m_statck_top];
m_objects_idle_flag[m_statck_top]=true;
}
}
~page(){release();}
void release()
{
if(NULL!=m_objects)delete[] m_objects;
if(NULL!=m_objects_statck)delete[] m_objects_statck;
if(NULL!=m_objects_idle_flag)delete[] m_objects_idle_flag;
}
void set_memory_error(){m_memory_error=true;release();}
bool memory_error()const{return m_memory_error;}
bool is_empty()const{return 0==m_statck_top;}
bool is_full()const{return m_statck_top==m_object_count;}
bool is_member(const Ptr& ptr){return ((ptr.m_p>=m_objects)&&(ptr.m_p<=&m_objects[m_object_count-1]));}
void operator >>(Ptr& ptr)
{
--m_statck_top;
m_objects_idle_flag[m_objects_statck[m_statck_top]-m_objects]=false;
ptr.m_p=m_objects_statck[m_statck_top];
}
TObjectPool_error operator <<(Ptr& ptr)
{
T* p=ptr.m_p;
long a=p-m_objects;
long b=(long)p-(long)m_objects;
if((b%sizeof(T))!=0)return TObjectPool_error_null_pointer;
if(is_full()||m_objects_idle_flag[a])return TObjectPool_error_multiple_return;
m_objects_idle_flag[a]=true;
m_objects_statck[m_statck_top]=p;
++m_statck_top;
ptr.m_p=NULL;
return TObjectPool_error_no;
}
private:
T* m_objects; //????
T** m_objects_statck; //??????????????
bool* m_objects_idle_flag; //???????
unsigned long m_statck_top; //?????0????????
unsigned long m_object_count; //????
bool m_memory_error; //??????
};
std::list<page*> m_lspage;
std::list<page*>::iterator m_current_page;
unsigned long m_per_page_object_count;
unsigned long m_idle_object_count; //??????
TObjectPool_error m_error; //????
};
//end
//////////////////////////////////
//TObjectPool Class template implement
//////////////////////////////////////
template <typename T>
TObjectPool<T>::TObjectPool(unsigned long per_page_object_count)
:m_per_page_object_count(per_page_object_count),m_idle_object_count(0),m_error(TObjectPool_error_no)
{
m_lspage.push_back(new page(m_per_page_object_count));
m_current_page=m_lspage.begin();
if((*(*m_current_page)).memory_error()){m_error=TObjectPool_error_memory;return;}
m_idle_object_count+=m_per_page_object_count;
}
//????????????new?????
struct DeleteObject{
template<typename T>
void operator()(T* p)const{delete p;}
};
template <typename T>
TObjectPool<T>::~TObjectPool(){std::for_each(m_lspage.begin(), m_lspage.end(),DeleteObject());}
template <typename T>
bool TObjectPool<T>: perator >>(TObjectPool<T>::Ptr& ptr)
{
if(m_error!=TObjectPool_error_no)return false;
if(ptr){if(!operator <<(ptr))return false;}
std::list<TObjectPool<T>::page*>::iterator end=m_current_page;
for(; m_current_page!=m_lspage.end(); ++m_current_page)
{
if(!(*(*m_current_page)).is_empty()) //????????????
{
--m_idle_object_count; //????????????????1
(*(*m_current_page))>>(ptr);
return true;
}
}
for(m_current_page=m_lspage.begin(); m_current_page!=end; ++m_current_page)
{
if(!(*(*m_current_page)).is_empty()) //????????????
{
--m_idle_object_count; //????????????????1
(*(*m_current_page))>>(ptr);
return true;
}
}
//???????????????????????????????
m_lspage.push_back(new page(m_per_page_object_count));
m_current_page=m_lspage.end();
--m_current_page;
if((*(*m_current_page)).memory_error()){m_error=TObjectPool_error_memory;return false;}
m_idle_object_count+=m_per_page_object_count-1; //???????????????-1
(*(*m_current_page))>>(ptr);
return true;
}
template <typename T>
bool TObjectPool<T>::operator <<(TObjectPool<T>::Ptr& ptr)
{
if(m_error!=TObjectPool_error_no)return false;
if(!ptr)
{
m_error=TObjectPool_error_null_pointer;
return false;
}
bool ok=false;
std::list<TObjectPool<T>::page*>::iterator end=m_current_page;
for(; m_current_page!=m_lspage.end(); ++m_current_page)
{
if((*(*m_current_page)).is_member(ptr))//????????
{
TObjectPool_error Ret=(*(*m_current_page))<<(ptr);
if(TObjectPool_error_no!=Ret)
{
m_error=Ret;
return false;
}
++m_idle_object_count; //????????????????1
ok=true;
break;
}
}
if(!ok)
{
for(m_current_page=m_lspage.begin(); m_current_page!=end; ++m_current_page)
{
if((*(*m_current_page)).is_member(ptr))//????????
{
TObjectPool_error Ret=(*(*m_current_page))<<(ptr);
if(TObjectPool_error_no!=Ret)
{
m_error=Ret;
return false;
}
++m_idle_object_count; //????????????????1
ok=true;
break;
}
}
}
//??????????2?????????????????????????????
if(m_idle_object_count>=(m_per_page_object_count<<1))
{
//????????????????
for(std::list<TObjectPool<T>::page*>::iterator i=m_lspage.begin(); i!=m_lspage.end();)
{
if((*(*i)).is_full())
{
delete *i;
i=m_lspage.erase(i);
m_idle_object_count -= m_per_page_object_count;
}
else ++i;
}
}
return true;
}
};
#endif
???
#include <iostream>
#include"TObjectPoolV12.h"
using namespace std;
using namespace Aura;
class CStudent
{
public:
long age;
long money;
long id;
};
void printa(const TObjectPool<CStudent>::Ptr& i)
{
if(i)cout<<"???"<<i->age<<"?"<<endl;
}
int main()
{
TObjectPool<CStudent> SOP(200);
TObjectPool<CStudent>::Ptr p[100];
for(int i=0; i<100;++i)SOP>>p;
cout<<TObjectPool_error_strings[SOP.error()]<<endl;
p[0]->age=10;
printa(p[0]);
for(i=0; i<100;++i)SOP<<p;
cout<<TObjectPool_error_strings[SOP.error()]<<endl;
return 0;
}
|
|