弱回调
、把shared_ptr绑(boost::bind)到boost::function里,那么回调的时候StockFactory对象始终存在,是安全的。但延长了生命期。
像之前的析构函数问题,有时候我们需要知道对象是否或者,就像Observeable::notifyObservers()那样,称之为“弱回调”。这里再次用到weak_ptr,将shared_ptr改为weak_ptr,生命期就不会延长了。在想要回调时检查是否可以提升就能知道对象存在与否。
代码如下:
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];
pStock = wkStock.lock();
if(!pStock)
{
pStock.reset(new Stock(key),boost::bind(&StockFactory::weakDeleteCallback,boost::weak_ptr<StockFactory>(shared_from_this),l));
wkStock = pStock;
}
}
return pStock;
private:
static void weakDeleteCallback(const boost::weak_ptr<StockFactory> &wkFactory,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;
};
经过测试,无论Stock和StockFactory谁先结束都不会影响程序的正确运行。在实际使用中,所有的Factory都是单例下的,在程序运行过程中不会销毁,一般也就不会出现此问题,但这种思想在事件通知中非常有用。本例只对单个Stock对象操作,如果对多个对象遍历操作,多线程下就可能造成死锁,在后面会解决。