在准备面试 or 考研,发现了对象池管理,自己就试着写一下吧。
前置知识
泛型、智能指针、内存管理
解决场景
如果出现对象频繁的创建或者删除时,可以考虑使用对象池。
具体实现
具体的思路即为对象内存的复用。
利用智能指针的性质(这里特质 u n i q u e unique unique指针),原因是因为 u n i q u e unique unique指针只可以一个对象指向同一个内存,并且在执行 m o v e move move函数时,之前指针内容会全部销毁。
所以可以根据内存复用的原则,保留一个 v e c t o r vector vector用来存储已经申请过的对象内存,获取内存时,首先向内存池获取看是否有空余对象内存,如果有直接赋值,如果没有则需要自行获取内存。
测试截图:
可以看到本身需要三个内存空间,经过对象内存池,只需要两个即可。
Code
/*** keep hungry and calm CoolGuang! ***/
//#pragma GCC optimize(3)
#include <bits/stdc++.h>
#define debug(x) cout<<#x<<":"<<x<<endl;
#define dl(x) printf("%lld\n",x);
#define di(x) printf("%d\n",x);
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
const ll INF= 1e18+7;
const int maxn = 1e6+7;
const int mod= 1e9+7;
const double eps = 1e-9;
const double PI = acos(-1);
ll m,p;
template<typename T>
class ObjectPool{
public:
std::unique_ptr<T> get(){
if(v.size() == 0) return NULL;
if(v.size() == MaxNum){
throw "Pool is Full";
}
auto t = move(v.back());
v.pop_back();
return std::move(t);
}
void del(unique_ptr<T> &p){ v.push_back(move(p));}
bool IsEmpty(){return v.size()==0;}
int Size() const{return v.size();}
private:
const int MaxNum = 1000;///最大对象数
vector<unique_ptr<T>>v;///分管已被创建的 处于未用状态的
};
class test{
public:
test(int _idx){
idx = _idx;
printf("%d test constructed\n",idx);
}
~test(){
printf("%d test destroyed\n",idx);
}
void WriteIdx(){printf("test id = : %d\n",idx);}
private:
int idx;
};
ObjectPool<test> *pool = new ObjectPool<test>();
int cnt = 0;
void GetWork(auto &p){
p = pool->get();
if(p == NULL) p = make_unique<test>(++cnt);
p->WriteIdx();
}
int main(){
unique_ptr<test> a = NULL,b = NULL,c = NULL;
GetWork(a);
GetWork(b);
pool->del(b);///放入对象池
GetWork(c);
return 0;
}