1.shared_ptr的删除器(deleter)
可以在 shared_ptr 的构造函数 和 reset 函数里面给 shared_ptr 加入 deleter。
定义:
template
template
deleter的作用是:deleter可以是一个函数或者是仿函数。在调用 shared_ptr 的析构函数的时候会有一个 delete 操作,现在提供的这个 deleter,就是用来替代delete的。
会执行:d(p)
ex:
shared_ptr
那么在调用 shared_ptr的析构函数的时候 delete p 会被替换为 delFun(p)
2.weak_ptr的lock函数:
weak_ptr.lock() 会把weak_ptr提升为一个 shared_ptr 对象,当 引用计数为0 ,那么 shared_ptr 为空。
ex:
shared_ptr
if(! shPtr)
{
//进入这里,表示引用计数为0;
return;
}
//在这里,说明引用计数不为0,成功的构造了一个 shared_ptr
3.下面一个例子来说明deleter和 weak.lock() 的使用
假设有 Stock 类,代表一只股票的价格。每一只股票有一个惟一的字符串标识,比如 Google 的 key 是 "NASDAQ:GOOG",IBM 是 "NYSE:IBM"。Stock 对象是个主动对象,它能不断获取新价格。为了节省系统资源,同一个程序里边每一只出现的股票只有一个 Stock 对象,如果多处用到同一只股票,那么 Stock 对象应该被共享。
为了达到上述要求,我们可以设计一个对象池 StockFactory。它的接口很简单,根据 key 返回 Stock 对象。如果stock对象不存在就创建一个。
(1)为了管理这个对象池StockFactory, 我们最初的设计如下:
class StockFactory : boost::noncopyable
{ // questionable code
public:
shared_ptr
private:
std::map
mutable Mutex mutex_;
};
这里有一个问题,shared_ptr
(2)我们知道weak_ptr不会延长对象的生命周期, weak_ptr只是对象一个observer。于是我们有下面的设计:
class StockFactory : boost::noncopyable
{
public:
shared_ptr
shared_ptr
MutexLock lock(mutex_);
weak_ptr
pStock = wkStock.lock(); // 尝试把weak_ptr提升为shared_ptr
if (!pStock) {
pStock.reset(new Stock(key));
wkStock = pStock; // 这里更新了 stocks_[key],注意 wkStock 是个引用
}
return pStock;
}
private:
std::map
mutable Mutex mutex_;
};
(3).上面的代码解决了延长对象生命周期的问题,但是仍然有问题,那就是即使对象已经不存在了,它仍然在 stocks_ 里面存在。 这样也可以叫做内存泄露。
为了解决这个问题,我们现在就要用到 shared_ptr 的 deleter 功能:这里deleter保证在删除stock的同时也删除 这个stock在 stocks_ 里面的存在。
class StockFactory : public boost::enable_shared_from_this
{
public:
shared_ptr
shared_ptr
MutexLock lock(mutex_);
weak_ptr
pStock = wkStock.lock();
if (!pStock) {
pStock.reset(new Stock(key),
boost::bind(&StockFactory::weakDeleteCallback,
boost::weak_ptr
_1));
wkStock = pStock;
}
return pStock;
}
private:
static void weakDeleteCallback(boost::weak_ptr
{
shared_ptr
factory->removeStock(stock);
}
delete stock; //
}
void removeStock(Stock* stock)
{
if (stock) {
MutexLock lock(mutex_);
stocks_.erase(stock->key());
}
}
private:
std::map
mutable Mutex mutex_;
};