template<class _Ty>
class ObjectPool
{
enum { nPollSize = 4 }; //最多三个对象
protected:
struct _Node
{
_Node* next;
};
_Node* front; //头
_Node* rear; //尾
private:
void ReFillPool() //填充
{
size_t total = sizeof(_Node) + sizeof(_Ty);
for (int i = 0; i < nPoolSize; ++i)
{
_Node* s = (_Node*)malloc(total); //_Node 和 对象大小都开辟出来
new(s + 1) _Ty(); //在指针后面构造对象
s->next = nullptr;
rear->next = s;
rear = s;
}
}
void InitPool() //初始化
{
if (rear != nullptr) return;
_Node* head = (_Node*)malloc(sizeof(_Node));
head->next = nullptr;
front = rear = head;
}
public:
ObjectPool() :front(nullptr), rear(nullptr)
{
InitPool();
}
~ObjectPool()
{
clear();
}
_Ty* allocObjMemory() //获得对象池
{
if (front == rear) //为空 注入对象
{
ReFillPool();
}
_Node* s = front->next; //不为空 取第一个结点
front->next = s->next;
if (s == rear)
{
rear = front;
}
return (_Ty*)(s + 1); //返回 _Ty 对象
}
void freeObjectMemory(void* pobj)
{
_Node* q = (_Node*)((char*)pobj - sizeof(_Node));
//减去4,回到_Node链表
q->next = rear->next; //将q 归还给链表 尾插
rear->next = q;
rear = q;
}
};
在构造链表的过程中,尽管链表只有一个next成员,但是由于在链表填充的过程中,多分配了一个对象的空间大小
则该链表结构变成,前面4字节为Node指针,后面的为对象的内存
再看下面的代码
template<class _Ty>
class ObjectPool
{
private:
enum { nPoolSize = 4 };
protected:
struct _Node
{
_Node* next;
};
_Node* front;
_Node* rear;
void InitPool() //初始化
{
_Node* s = (_Node*)malloc(sizeof(_Node));
s->next = nullptr;
front = rear = s;
ReFillPool();
}
void ReFillPool() //填充
{
int total = sizeof(_Node) + sizeof(_Ty);
for (int i = 0; i < nPoolSize; ++i)
{
_Node* s = (_Node*)malloc(total);
s->next = nullptr;
rear->next = s;
rear = s;
}
}
void Clear()
{
_Node* p = nullptr;
while (front->next != nullptr)
{
p = front->next;
front->next = p->next;
free p;
}
free front;
front = rear = nullptr;
}
public:
ObjectPool() :front(nullptr), rear(nullptr)
{
InitPool();
}
~ObjectPool()
{
Clear();
}
ObjectPool(const ObjectPool&) = delete;
ObjectPool& opertaor = (const ObjectPool&) = delete;
_Ty* allocObjMemory()
{
if (front == rear)
{
ReFillPool();
}
_Node* s = front->next;
front->next = s->next;
if (s == rear) rear = front;
return (_Ty*)((char*)s + sizeof(_Node));
}
void freeObjMemory(void* q)
{
_Node* p = (_Node*)(char*)q - sizeof(_Node);
p->next = nullptr;
rear->next = p;
rear = p;
}
};
class Point
{
private:
float _x;
float _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:
void* operator new(size_t sz) //静态方法 没有this指针
{
return malloc(sz);
}
//1. 计算大小
//2. 分配空间
//3. 返回地址 调用构造函数
void operator delete(void* p) //size_t sz
{
free(p);
}
//自动计算指针所指之物的大小,传递给delete
//系统将new delete默认定义为静态
};
int main()
{
Point* pa1 = new Point(1, 2);
delete pa1;
}
系统对象operator new 和 operator delete 的重载进行了作弊行为,系统会将他们自动定义为静态函数,并且会自动计算类型的大小进行传入
- operator new
- 计算大小
- 分配空间
- 返回地址 调用构造函数
- delete
- 自动计算指针所指之物的大小,传递给delete
根据下面代码,我们在operator new 与 operator delete 调度ObjectPool,但是这样并不属于我们将对象创建好再直接去使用,而是一个一个去构建
template<class _Ty>
class ObjectPool
{
private:
enum { nPoolSize = 4 };
protected:
struct _Node
{
_Node* next;
};
_Node* front;
_Node* rear;
void InitPool() //初始化
{
_Node* s = (_Node*)malloc(sizeof(_Node));
s->next = nullptr;
front = rear = s;
ReFillPool();
}
void ReFillPool() //填充
{
int total = sizeof(_Node) + sizeof(_Ty);
for (int i = 0; i < nPoolSize; ++i)
{
_Node* s = (_Node*)malloc(total);
s->next = nullptr;
rear->next = s;
rear = s;
}
}
void Clear()
{
_Node* p = nullptr;
while (front->next != nullptr)
{
p = front->next;
front->next = p->next;
free p;
}
free front;
front = rear = nullptr;
}
public:
ObjectPool() :front(nullptr), rear(nullptr)
{
InitPool();
}
~ObjectPool()
{
Clear();
}
ObjectPool(const ObjectPool&) = delete;
ObjectPool& opertaor = (const ObjectPool&) = delete;
_Ty* allocObjMemory()
{
if (front == rear)
{
ReFillPool();
}
_Node* s = front->next;
front->next = s->next;
if (s == rear) rear = front;
return (_Ty*)((char*)s + sizeof(_Node));
}
void freeObjMemory(void* q)
{
_Node* p = (_Node*)(char*)q - sizeof(_Node);
p->next = nullptr;
rear->next = p;
rear = p;
}
};
class Point
{
private:
static ObjectPool<Point> PointPool;
private:
float _x;
float _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:
void* operator new(size_t sz) //静态方法 没有this指针
{
return PointPool.allocObjMemory();
//函数本身没用this指针,成员属于私有成员,需要指针指向成员
//PointPool设计为静态对象
}
void operator delete(void* p) //size_t sz
{
PointPool.freeObjMemory(p);
}
};
int main()
{
Point* pa1 = new Point(1, 2);
Point* pa2 = new Point(3, 4);
delete pa1;
delete pa2;
return 0;
}
template<class _Ty>
class ObjectPool
{
private:
enum { nPoolSize = 4 };
protected:
struct _Node
{
_Node* next;
};
_Node* front;
_Node* rear;
void InitPool() //初始化
{
_Node* s = (_Node*)malloc(sizeof(_Node));
s->next = nullptr;
new(s + 1) _Ty(); //构建对象
front = rear = s;
ReFillPool();
}
void ReFillPool() //填充
{
int total = sizeof(_Node) + sizeof(_Ty);
for (int i = 0; i < nPoolSize; ++i)
{
_Node* s = (_Node*)malloc(total);
s->next = nullptr;
rear->next = s;
rear = s;
}
}
void Clear()
{
_Node* p = nullptr;
while (front->next != nullptr)
{
p = front->next;
front->next = p->next;
free(p);
}
free(front);
front = rear = nullptr;
}
public:
ObjectPool() :front(nullptr), rear(nullptr)
{
InitPool();
}
~ObjectPool()
{
Clear();
}
ObjectPool(const ObjectPool&) = delete;
ObjectPool& operator=(const ObjectPool&) = delete;
_Ty* allocObjMemory()
{
if (front == rear)
{
ReFillPool();
}
_Node* s = front->next;
front->next = s->next;
if (s == rear) rear = front;
return (_Ty*)((char*)s + sizeof(_Node));
}
void freeObjMemory(void* q)
{
_Node* p = (_Node*)(char*)q - sizeof(_Node);
p->next = nullptr;
rear->next = p;
rear = p;
}
};
template<class _Ty>
class ObjectPoolBase
{
public:
_Ty* GetObject() //获得对象
{
return objpool.allocObjMemory();
}
void RetObject(_Ty* p) //归还对象
{
objpool.freeObjMemory(p);
}
static ObjectPoolBase<_Ty>& instance()
{
static ObjectPoolBase<_Ty> objbase;
return objbase;
}
private:
using ClassTypePool = ObjectPool<_Ty>;
ClassTypePool objpool;
};
class Point
{
private:
static ObjectPool<Point> PointPool;
private:
float _x;
float _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:
void* operator new(size_t) = delete;
void operator delete(void*) = delete;
};
int main()
{
ObjectPoolBase<Point>& pointpool = ObjectPoolBase<Point>::instance();
Point* ap = pointpool.GetObject();
pointpool.RetObject(ap);
return 0;
}
这里添加ObjectPoolBase类型,使用单例模式来添加一个中间类,提供调用接口
template<class _Ty>
class ObjectPool
{
private:
enum { nPoolSize = 4 };
protected:
struct _Node
{
_Node* next;
};
_Node* front;
_Node* rear;
void InitPool() //初始化
{
if (rear != nullptr) return;
_Node* s = (_Node*)malloc(sizeof(_Node));
s->next = nullptr;
front = rear = s;
ReFillPool();
}
void ReFillPool() //填充
{
int 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;
}
}
void Clear()
{
_Node* p = nullptr;
while (front->next != nullptr)
{
p = front->next;
front->next = p->next;
free(p);
}
free(front);
front = rear = nullptr;
}
public:
ObjectPool() :front(nullptr), rear(nullptr)
{
InitPool();
}
~ObjectPool()
{
Clear();
}
ObjectPool(const ObjectPool&) = delete;
ObjectPool& operator=(const ObjectPool&) = delete;
_Ty* allocObjMemory()
{
if (front == rear)
{
ReFillPool();
}
_Node* s = front->next;
front->next = s->next;
if (s == rear) rear = front;
return (_Ty*)((char*)s + sizeof(_Node));
}
void freeObjMemory(void* q)
{
_Node* p = (_Node*)((char*)q - sizeof(_Node));
p->next = nullptr;
rear->next = p;
rear = p;
}
};
template<class _Ty>
class ObjectPoolBase
{
public:
_Ty* GetObject() //获得对象
{
return objpool.allocObjMemory();
}
void RetObject(_Ty* p) //归还对象
{
objpool.freeObjMemory(p);
}
static ObjectPoolBase<_Ty>& instance()
{
static ObjectPoolBase<_Ty> objbase;
return objbase;
}
private:
using ClassTypePool = ObjectPool<_Ty>;
ClassTypePool objpool;
};
class Point
{
private:
static ObjectPool<Point> PointPool;
private:
float _x;
float _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:
void operator delete(void*) = delete;
};
int main()
{
ObjectPoolBase<Point>& pointpool = ObjectPoolBase<Point>::instance();
Point* ap = pointpool.GetObject();
pointpool.RetObject(ap);
return 0;
}