问题: 需要1个StockFactory类,在用到时主动创建stock, 在stock不用时自动释放
方案1 shared_ptr
class Stock;
class StockFactory
{
public:
...
std::shared_ptr<Stock> getStock(const std::string &stockName);
private:
std::map<std::string, std::shared_ptr<Stock>> _stocks;
MutexLock _mutex;
};
std::shared_ptr StockFactory::getStock(const std::string& key)
{
MutexLockGuard guard(_mutex);
return _stocks[key];
}
此方案存在: 由于_stocks中保存的时shared_ptr, 所以会存在申请的shared_ptr计数最少为1,永远不会释放,存在内存泄漏。
方案2 weak_ptr
class StockFactory
{
public:
...
std::shared_ptr StockFactory::getStock(const std::string &key)
private:
std::map<std::string, std::weak_ptr<Stock>> _stocks;
};
std::shared_ptr StockFactory::getStock(const std::string &key)
{
MutexLockGuard guard(_mutex);
auto wk = _stocks[key];
if(wk.lock() == nullptr)
{
_stocks.erase(key);
_stocks[key] = std::make_shared<Stock>();
}
return _stocks[key];
}
但是该方案还存在问题,_stocks中的weak_ptr也不会被释放。注意方案1的问题是对象不能释放,这个方案的是weak_ptr这个指针不能被释放。解决办法见方案3
方案3 shared_ptr的deleter方案
方案3就是利用shared_ptr的deleter,在Stock被释放时,自动调用StockFactory的delete删除_stocks中的对应内容
void StockFactory::deleteStock(Stock* st)
{
std::cout << "deleteStock" << st->key() << std::endl;
if(st)
{
MutexLockGuard guard(_mutex);
_stocks.erase(st->key());
}
delete st;
}
std::shared_ptr<Stock> StockFactory::getStock(const std::string &key)
{
std::cout << "getStock: " << key << std::endl;
std::weak_ptr<Stock> wk;
{
MutexLockGuard guard(_mutex);
wk = _stocks[key];
}
std::shared_ptr<Stock> sp;
if(wk.lock() == nullptr)
{
sp = std::shared_ptr<Stock>(new Stock(), std::bind(&StockFactory::deleteStock, this, _1));
}
{
MutexLockGuard guard(_mutex);
_stocks.erase(key);
_stocks[key] = sp;
}
return sp;
}
但这样还存在问题,该方案把this传给deleter,可能会出现this已经被释放,但是在deleter中被调用。