当前位置: 首页 > 科技观察

你是否亲手掌握了一个对象池?

时间:2023-03-12 21:12:03 科技观察

什么是对象池?对象池,类似于线程池和内存池,减少了频繁创建和销毁对象(尤其是消耗大量资源的对象)的成本,可以用来实现对象的缓存和重用。这也是一种设计模式。话不多说,直接上代码:#include#include#include#include#include#include#include#includestructA{A(std::strings){str_=std::move(s);}voidprint(){std::cout<>classObjectPool{public:ObjectPool()=default;~ObjectPool(){assert(freeObjects_.size()==kInitChunkSize*(std::pow(2,pool_.size())-1));size_tchunkSize{kInitChunkSize};for(auto*chunk:pool_){allocator_.deallocate(chunk,chunkSize);chunkSize*=2;}pool_.clear();}templatestd::shared_ptracquireObject(Args...args){if(freeObjects_.empty()){addChunk();}T*object{freeObjects_.back()};new(object)T{std::forward(args)...};freeObjects_.pop_back();returnstd::shared_ptr(object,[this](T*object){std::_Destroy(object);freeObjects_.push_back(object);});}private:std::vectorpool_;std::vectorfreeObjects_;staticconstsize_tkInitChunkSize{5};size_tnewChunkSize{kInitChunkSize};voidaddChunk(){std::cout<<"addChunk\n";auto*firstNewObject{allocator_.allocate(newChunkSize)};pool_.push_back(firstNewObject);autooldFreeObjectSize{freeObjects_.size()};freeObjects_.resize(oldFreeObjectSize+newChunkSize);std::iota(std::begin(freeObjects_)+oldFreeObjectSize,std::end(freeObjects_),firstNewObject);newChunkSize*=2;}Allocatorallocator_;};usingAPool=ObjectPool;intmain(){APoolpool;for(inti=0;i<20;i++){autox=pool.acquireObject(std::string("hello"));x->print();}return0;}上面的对象池实现在每次请求对象时都会调用构造函数和析构函数,这里可以选择是否需要根据实际情况来调用。如果建造和销毁的成本比较高,可以想办法节省相应的成本。