对象池ObjectPool(基础)

template<class _Ty>
class ObjectPool
{
  void *ReFilePool()
  void  InitPool();
  enum { nPoolSize = 4 } ;
protected :
  struct  _Node
  {
    _Node* next;
  };
    _Node* front;
   _Node* rear ;
public:
  ObjectPool():front(nullptr),rear(nullptr)
  {
     InitPool();
  }
  ~ObjectPool()
  {
    clear();
  }

 ObjectPool(const ObjectPool&) = delete; //移除拷贝构造函数
 ObjectPool& operator = (const ObjectPool&) = delete;
 
 _Ty *allocObjMemory() //获取对象的存储空间
 void  freeObjMemory(void* pobj) //释放对象的存储空间

InitPool函数 – 初始化对象池

void *InitPool()
{
   _Node* head = (Node*)malloc(sizeof(_Node));
   head->next = nullptr;
   front = rear = head;
   ReFilePool(); //创建nPoolSize 个对象
}

Clear函数 – 清除对象池

void* Clear()
{
  _Node* p = nullptr;
  while(front->next != nullptr)
  {
     p = front->next;
     front->next = p->next;
     free(p);
  }
  free(front); //删除头标记
  front = rear = nullptr;
}

ReFilePool函数 – 填充对象池

void *ReFilePool()
{
   size_t total = sizeof(_Node) + sizeof(_Ty);
   for(int i = 0;i<nPoolSize;i++)
   {
      _Node* s= (_Node*)malloc(total);
      new(s + 1) _Ty();
      s->next = nullptr;
      rear->next = s;
      rear = s;
   }   
   ReFilePool(); //创建nPoolSize 个对象
}

allocObjMemory函数 – 从池中获取一个对象

_Ty* allocObjMemory() //获取对象的存储空间
{
   if( rear == front) //池子为空
   {
      ReFilePool(); //重新注入nPoolSize 个对象
   }
   _Node* s = front->next;
   front->next = s->next;
   if(s == front)
   {
      rear = front;
   }
   return(_Ty*)(s+1); //s是_Node指针,+1操作使其移动sizeof(_Node)个字节,指向了数据对象所在空间
}

freeObjMemory函数 – 回收(释放)对象的存储空间

void freeObjMemory(void* pobj)
{
  _Node *q = (_Node*)((char*)pobj - sizeof(_Node)); //使q指向数据对象之上的_Node空间
  q->next = nullptr;
  rear->next = q;
  rear = q;
}

对象池的实例

例1:


class Point
{
private:
  static ObjectPool<Point> PointPool;//创建对象池 创建为static对象是为了下面的static方法正常访问
  f1oat _x;
  f1oat _y ;
public:
  Point (float x = 0.0f,float y = 0.0f):_x(x)_y(y)
  Point(const Point&) = default;
  Point& operator=(const Point&) = default;
  ~Point() {}
public:
  /*系统会将new重载 与 delete 编译为static函数,即内部不存在this指针;
  这是因为对于malloc()与free()函数本身在调用时系统会直接计算吃对象的的大小;
  在重载时就不需要依赖于this指针获得对象内部的信息,因此编译为static函数
  */
  
  void* operator new(size_t sz) 
  {
    //return malloc(sz) ;  常规的申请空间
    return PointPool.allocObjMemory(); //用对象池来分配空间
  )
  void operator delete(void* p)
  {
  //   return free(p) ;  常规的释放空间
      PointPool.freeObjMemory(p);   //用对象池来释放空间
  }
};

 ObjectPool<Point> Point::PointPool; //静态成员的类外初始化

int main ()
{
  Point* pa1 = new Point(12); 
  Point* pa2 = new Point(34); 
  
  delete pa1; 
  delete pa2; 
  return 0:
}

例2:

template<class _Ty> //中间基类
class ObjectBase
{
public:
  _Ty* Getoblject({
    return objpool.allocObjMemory () ;
  }
  void RetObject(_Ty* p)
  {  
    objpool.freeObjMemory(p);
  }

  static ObjectPoolBase<_Ty>& instance(){{
    static ObjectPoolBase<_Ty> objbase;
    return objbase;
  }
};

class Point
{
private:
  f1oat _x;
  f1oat _y ;
public:
  Point (float x = 0.0f,float y = 0.0f):_x(x)_y(y)
  Point(const Point&) = default;
  Point& operator=(const Point&) = default;
  ~Point() {}
public:
//依靠中将基类实现对池的获取与释放,因此不需要new与delete函数
  void* operator new(size_t sz) = delete;
  void operator delete(void*) = delete;
};



int main ()
{
  ObjectPoolBase<point>& PointPool =  ObjectPoolBase<point>::instance();

  Point* ap = PointPool.GetObject();  //从池中获取对象

  PointPool.RetObject(ap);  //将对象归还
   
  return 0:
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值