C++对象池
参考链接:https://blog.csdn.net/gx864102252/article/details/81174993
概念
??顾名思义,对象池就是用于预先存放一堆对象的池子,思路如下:
- 预先初始化创建一系列对象(或者从外部加载创建)。
- 从对象池中取出一个对象。
- 使用完之后自动回收自对象池。
??对象池有很多场景都可以使用,例如:一个对象构造很消耗时间,又或者一些对象被很频繁地使用和销毁(内存碎片),都可以使用对象池。它的思想类似于数据库连接池、网络句柄连接池等。
??在C++中借助智能指针,可以很方便的实现一个对象池,智能指针提供的方法可以自定义删除器,在智能指针需要释放的时候调用删除器,将对象重新放入对象池即可。
??这里关键要注意:
- 自定义删除器(需要重新压入构建的对象池)
- shared_ptr或者unique_ptr
细节
??自定义删除器只做一件事,就是将对象重新放入对象池。如果对象池初始化的时候就自定义删除器的话,那么在放回的时候是无法再定义一个这样的删除器的(删除器中的逻辑是将对象放回对象池),所以这种做法行不通。
??需要注意,回收的对象只能是默认删除器本身(智能指针指向的对象)。除了前述原因之外,另外一个原因是对象池释放的时候需要释放所有的智能指针,释放的时候如果存在自定义删除器将会导致对象无法释放。
??只有在Get的时候定义删除器才行,但是初始创建或加入的智能指针是默认删除器,所以我们需要把智能指针的默认删除器改为自定义删除器。
代码实现
SimpleObjectPool.hpp
#pragma once
#include <functional>
#include <memory>
#include <list>
#include <typeinfo>
#include <iostream>
namespace U
{
template<typename T>
const char* UGetClassName()
{
const char* pName = typeid(T).name();
return pName;
}
template<class T>
class SimpleObjectPool
{
public:
using TypeCB = std::function<void(T*)>;
void Add(std::unique_ptr<T> t)
{
objPool.push_back(std::move(t));
}
std::unique_ptr<T, TypeCB> Get()
{
std::function<void(T*)> funcCB = [this](T* t)->void {
objPool.push_back(std::unique_ptr<T>(t));
std::cout << "删除缓冲区" << std::endl;
};
if (objPool.empty())
{
Add(std::unique_ptr<T>(new T(1024)));
}
std::unique_ptr<T, TypeCB> ptr(objPool.back().release(), funcCB);
objPool.pop_back();
return std::move(ptr);
}
bool Empty() const
{
return objPool.empty();
}
int CurSize() const
{
return objPool.size();
}
~SimpleObjectPool()
{
while (!objPool.empty())
{
objPool.back().reset();
objPool.pop_back();
}
}
private:
std::list<std::unique_ptr<T>> objPool;
};
}
main.cpp
static U::SimpleObjectPool<class DataBuffer> g_objPool;
class DataBuffer
{
private:
char* data;
int len;
public:
DataBuffer(int len)
{
data = new char[len];
this->len = len;
}
~DataBuffer()
{
if (data != nullptr)
{
delete data;
data = nullptr;
}
}
char* const GetBuffer() const
{
return this->data;
}
int GetLen() const
{
return this->len;
}
};
struct STA
{
STA()
{
std::cout << "create" << endl;
}
STA(int i)
{
a = i;
std::cout << "create int" << endl;
}
STA(const STA& other)
{
*this = other;
std::cout << "copy" << endl;
}
~STA()
{
std::cout << "delete" << endl;
}
int a = 0;
};
void InitObjPool(int count)
{
std::cout << "对象池初始化" << std::endl;
for (int i = 0; i < count; i++)
{
g_objPool.Add(std::unique_ptr<DataBuffer>(new DataBuffer(1024)));
}
}
int main(int argc, char* argv[])
{
U::SimpleObjectPool<STA> pool;
pool.Add(std::unique_ptr<STA>(new STA()));
pool.Add(std::unique_ptr<STA>(new STA()));
{
auto ptr = pool.Get();
pool.Get();
cout << "pool size:" << pool.CurSize() << endl;
}
cout << "pool size:" << pool.CurSize() << endl;
{
pool.CurSize();
pool.CurSize();
cout << "pool size:" << pool.CurSize() << endl;
}
cout << "pool size:" << pool.CurSize() << endl;
system("pause");
return 0;
}
效果展示:
|