std::bind

问题: 需要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中被调用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值