做高端网站/seo优化技术是什么
C++ 公共组件-对象池实现
对象池
对象池对于创建开销比较大的对象来说很有意义,为了避免重复创建开销比较大的对象,可以通过对象池来优化。对象池的思路比较简单,事先创建好一批对象,放到一个集合中,每当程序需要新的对象时,就从对象池中获取,程序用完该对象后都会把该对象归还给对象池。这样会避免重复创建对象,提高程序性能。
基于C++11 简单实现对象池
1、这里需要注意的是,对象被回收之后它的状态并没有被清除,用户从池中获取对象之后最好先初始化或重置一下状态。
2、在对象池中创建不同的对象时,构造函数入参的引用将被忽略,即入参int和int&的构造函数会被认为是同一种类型的构造函数,因为在构造对象时无法获取变参Args…的引用类型,丢失了引用相关的信息。
3、github源码地址
#include<string>
#include<functional>
#include<memory>
#include<unordered_map>
#include <iostream>
using namespace std;const int MaxObjectNum = 10;class NonCopyable{
protected:NonCopyable() = default;virtual ~NonCopyable() = default;
public:NonCopyable(const NonCopyable&) = delete; // 禁用复制构造NonCopyable& operator = (const NonCopyable&) = delete; // 禁用赋值构造
};template<typename T>
class ObjectPool : NonCopyable{template<typename... Args>using Constructor = std::function<std::unique_ptr<T>(Args...)>;using DelType = std::function<void(T*)>;public:// 默认创建多少个对象template<typename... Args>void Init(size_t num, Args&&... args){if (num<= 0 || num> MaxObjectNum)throw std::logic_error("object num out of range.");auto constructName = typeid(Constructor<Args...>).name(); // 不区分引用for (size_t i = 0; i <num; i++){m_object_map.emplace(constructName, std::unique_ptr<T>(new T(std::forward<Args>(args)...)));}}// 从对象池中获取一个对象template<typename... Args>std::unique_ptr<T,DelType> Get(){string constructName = typeid(Constructor<Args...>).name();auto range = m_object_map.equal_range(constructName);for (auto it = range.first; it != range.second; ++it){std::unique_ptr<T, DelType> ptr(it->second.release(), [this,constructName](T* p){m_object_map.emplace(constructName,unique_ptr<T>(p)); //删除函数执行的操作});m_object_map.erase(it);return ptr;}return nullptr;}inline size_t Size() const{return m_object_map.size();}inline bool empty() const{return m_object_map.empty();}
private:unordered_multimap<string, std::unique_ptr<T>> m_object_map;
};/*-----------------------------*/
struct BigObject{BigObject() = default;explicit BigObject(int a) {};BigObject(const int& a, const int& b){}void Print(const string& str){cout <<str<< endl;}
};template <typename T>
void Print(T&& p, const string& str){if (p != nullptr){p->Print(str);}
}void TestObjPool(){ObjectPool<BigObject> pool;pool.Init(2); // 初始化对象池,初始创建两个对象{auto p = pool.Get();Print(std::move(p), "p");pool.Get();std::cout<<"pool.size()="<<pool.Size()<<std::endl;}// 出了作用域之后,对象池返回出来的对象又会自动回收std::cout<<"pool.size()="<<pool.Size()<<std::endl;{pool.Get();pool.Get();std::cout<<"pool.size()="<<pool.Size()<<std::endl;}std::cout<<"pool.size()="<<pool.Size()<<std::endl;// 对象池支持重载构造函数{pool.Init(2, 1);auto p4 = pool.Get<int>();Print(std::move(p4), "p4");pool.Init(2, 1, 2);auto p5 = pool.Get<int, int>();Print(std::move(p5), "p5");}std::cout<<"pool.size()="<<pool.Size()<<std::endl;
}int main(){TestObjPool();return 0;
}