class StockFactory:public boost::enable_shared_from_this<StockFactory>,
boost::noncopyable
{
public:
shared_ptr<Stock> get(const string& key){
shared_ptr<Stock> pStock;
MutexLockGuard lock(mutex_);
weak_ptr<Stock>& wkStock=stocks_[key]; //注意wkStock是引用
if(!pStock){
pStock.reset(new Stock(key),
boost:bind(&StockFactory::weakDeleteCallback,
boost::weak_ptr<StockFactory>(shared_from_this),
_1));
//上面必须强制把shared_from_this()转型为weak_ptr,才不会延长生命期,
//因为boost:bind拷贝的是实参类型,不是形参类型
wkStock=pStock;
}
return pStock;
}
private:
static void weakDeleteCallback(const boost:weak_ptr<StockFactory>& wkFactor,
Stock* stock){
shared_ptr<StockFactory>factory(wkFactory.lock());//尝试提升
if(factory){
factory->removeStock(stock);
}
delete stock;
}
void removeStock(Stock* stock){
if(stock){
MutexLockGuard lock(mutex_);
stocks_erase(stock->key);
}
}
private:
mutable MutexLock mutex_;
std::map<string, weak_ptr<Stock>>stocks_;
}
两个简单的测试:
void testLongLifeFactory(){
shared_ptr<Stock> stock=fatcory->get("NYSE:IBM");
shared_ptr<Stock> stock2=fatcory->get("NYSE:IBM");
assert(stock==stock2);
}
void testShortLifeFactory(){
shared_ptr<Stock> stock;
{
shared_ptr<StockFatcory> fatcory(new StockFatcory);
stock=fatcory->get("NYSE:IBM");
shared_ptr<Stock> stock2=fatcory->get("NYSE:IBM");
assert(stock==stock2);
}
}