对象池
举例:
class StockFactory : boost::noncopyable
{
public:
shared_ptr<Stock> get(const string& key);
private:
mutable MutexLock mutex;
std::map<string,shared_ptr<Stock> > stock;
};
这段代码中有一个问题,Stock对象永远不会被销毁,因为map里存的是shared_ptr,那就改为weak_ptr:
class StockFactory : boost::noncopyable
{
public:
shared_ptr<Stock> get(const string& key);
private:
mutable MutexLock mutex;
std::map<string,weak_ptr<Stock> > stocks;
};
shared_ptr<Stock> StockFactory::get(const string& key)
{
shared_ptr<Stock> pStock;
MutexLockGuard lock(mutex);
weak_ptr<Stock>& wkStock = stocks[key];
pStock = wkStock.lock();
if(!pStock)
{
pStock.reset(new Stock(key));
wkStock = pStock;
}
return pStock;
}
解决了对象不销毁的问题,但是程序有轻微的内存泄漏,因为map大小只增不减。
针对这个问题,可以利用shared_ptr的定制析构功能。shared_ptr的额外模板类型参数可以传入一个函数指针或仿函数,在析构时就可以执行该函数来达到目的。
template<class Y,class D>shared_ptr::shared_ptr(Y* p,D d);
template<class Y,class D>shared_ptr::reset(Y* p,D d);
class StockFactory : boost::noncopyable
{
public:
shared_ptr<Stock> get(const string& key);
private:
mutable MutexLock mutex;
std::map<string,weak_ptr<Stock> > stocks;
void deleteStock(Stock* stock)
{
if(stock)
{
MutexLockGuard lock(mutex);
stocks.erase(stock->key());
}
delete stock;
}
};
shared_ptr<Stock> StockFactory::get(const string& key)
{
shared_ptr<Stock> pStock;
MutexLockGuard lock(mutex);
weak_ptr<Stock>& wkStock = stocks[key];
pStock = wkStock.lock();
if(!pStock)
{
pStock.reset(new Stock(key),boost::bind(&StockFactory::deleteStock,this,l));
wkStock = pStock;
}
return pStock;
}
这样就做到了在析构Stock对象的同时将对应的map中的变量也删除。这里暴露了this指针会有线程安全问题,在后面解决。