const int MaxObjectNum = 10; template <typename T> class ObjectPool { template <typename... Args> using Constructor = std::function<std::shared_ptr<T>(Args...)>; public: ObjectPool(void) : m_bNeedClear(false) { } virtual ~ObjectPool(void) { m_bNeedClear = true; } 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::shared_ptr<T>(new T(std::forward<Args>(args)...), [constructName, this] (T* t) { if (m_bNeedClear) { delete t; } else { m_object_map.emplace(constructName, std::shared_ptr<T>(t)); } })); } } template <typename... Args> std::shared_ptr<T> Get() { string constructName = typeid(Constructor<Args...>).name(); auto range = m_object_map.equal_range(constructName); for (auto it = range.first; it != range.second; ++it) { auto ptr = it->second; m_object_map.erase(it); return ptr; } return nullptr; } private: std::multimap<std::string, std::shared_ptr<T> > m_object_map; bool m_bNeedClear; };
testmain.cpp
class BigObject { public: BigObject(){} BigObject(int a){} BigObject(const int& a, const int& b) { } void Print(const string& str) { cout << str << endl; } }; void Print(shared_ptr<BigObject> p, const string& str) { if (p != nullptr) { p->Print(str); } } int main() { ObjectPool<BigObject> pool; pool.Init(2); { auto p = pool.Get(); Print(p, "p"); auto p2 = pool.Get(); Print(p2, "p2"); } auto p = pool.Get(); Print(p, "p"); auto p2 = pool.Get(); Print(p2, "p2"); auto p3 = pool.Get(); Print(p3, "p3"); pool.Init(2, 1); auto p4 = pool.Get<int>(); Print(p4, "p4"); getchar(); return 0; }