版本3问题: 不支持参数不同的构造函数。
版本4 设计:
通过可变参数模板来解决。可变参数模板可以支持不同参数的构造函数来创建对象。
#define LOG(info) \
cout << __FILE__ << ":" << __LINE__ << " " \
<< __TIMESTAMP__ << " : " << info << endl;
const int MaxTotal = 10; // 池对象总数
const int MaxIdle = 10; // 最大空闲对象数
const int MinIdle = 0; // 最小空闲对象数
template<class T>
class ObjectPool
{
private:
class ObjectDeleter
{
ObjectPool* _pool;
public:
ObjectDeleter(ObjectPool* p) :_pool(p) {}
void operator()(T* pobj) const
{
if (_pool->needClose)
{
delete pobj;
}
else
{
//if (std::erase_if(_pool->m_active_object_queue, [pobj]
(shared_ptr<T>& p)
// {
return p.get() == pobj;
// }
//))
{
LOG("对象已经归还");
_pool->m_idle_object_queue.emplace_back(std::shared_ptr<T>(pobj,
ObjectDeleter(_pool)));
}
_pool->numActive -= 1;
}
}
};
private:
//bool needClose = false; // 需要关闭标记
//int numActive = 0; //活动对象个数
//int createCount = 0; // 创建对象个数
//int destroyCount = 0; // 销毁对象个数
bool needClose; // 需要关闭标记
int numActive; //活动对象个数
int createCount; // 创建对象个数
int destroyCount; // 销毁对象个数
std::deque<std::shared_ptr<T> > m_active_object_queue; // 活动队列,借
出对象存储的队列
std::deque<std::shared_ptr<T> >m_idle_object_queue; // 空闲队列
public:
ObjectPool() :needClose(false), numActive(0), createCount(0),
destroyCount(0) {}
ObjectPool(const ObjectPool&) = delete;
ObjectPool& operator=(const ObjectPool&) = delete;
~ObjectPool()
{
Close();
}
void Close() // 关闭对象池
{
LOG("关闭对象池");
needClose = true;
Clear();
}
void Clear() // 清空对象池
{
//m_active_object_queue.clear();
m_idle_object_queue.clear();
createCount = 0;
}
size_t GetNumIdle() const
{
return m_idle_object_queue.size();
}
size_t GetNumActive() const
{
return numActive;
}
template<class...Args>
void Init(size_t num,Args&& ...args)
{
if (needClose)
{
LOG("对象池已关闭");
return; //exit(1);
}
if (num <= 0 || num > MaxTotal)
{
LOG("对象数量超出范围");
exit(1);
}
createCount += num;
for (size_t i = 0; i < num; ++i)
{
//shared_ptr<T> sp = shared_ptr<T>(new T(),ObjectDeleter(this));
//m_idle_object_queue.push_back(sp);
m_idle_object_queue.push_back(
shared_ptr<T>(
new T(std::forward<Args>(args)...),
ObjectDeleter(this)
)
);
}
}
public:
template<class... Args>
void AddObject(Args...args)
{
Init(1,std::forward<Args>(args)...);
}
template<class... Args>
std::shared_ptr<T> borrowObject(Args...args) //借对象
{
if (needClose)
{
LOG("对象池已关闭,无法借对象");
return nullptr;
}
if (m_idle_object_queue.size() == 0)
{
LOG("空袭队列空,无对象可借");
if (createCount - numActive - destroyCount >= MaxTotal)
{
LOG("对象池中对象的个数已到达上限");
return nullptr; // exit(1);
}
AddObject(std::forward<Args>(args)...);
LOG("增加对象成功");
}
shared_ptr<T> sp = m_idle_object_queue.front();
m_idle_object_queue.pop_front();
//m_active_object_queue.push_back(sp);
numActive += 1;
return sp;
}
void returnObject(std::shared_ptr<T>& sp)
{
sp.reset();
}
};
// 测试
int main()
{
ObjectPool<Point> objpool;
objpool.Init(3,1,2);
shared_ptr<Point> ps = objpool.borrowObject();
return 0;
}