美文网首页
Effective STL 第7条

Effective STL 第7条

作者: 懒生活 | 来源:发表于2022-08-22 23:11 被阅读0次

    容器中的对象如果是指针,指针指向的资源,容器没有办法自动释放.

    问题引出

    容器在自己析构的时候,会把包含的对象逐个析构掉. 这样容器包含的对象占用的资源就会被正确释放. 但如果容器里面存放的是指针,普通指针并没有析构函数,那么指针指向的资源,并不能被触发进行释放.

    void main()
    {
      vector<Widget*> vwp;
      for(int i = 0;i<10;i++)
      {
        vwp.push_back(new Widget);
      }
    }
    
    

    当main函数执行完毕的时候,就有10个new的Widget对象泄露.

    粗陋的解决方法

    在使用完vwp容器之后,对容器内的指针手动释放一次

    for(auto it=vwp.begin();it!=vwp.end();it++)
      delete *it;
    

    用for_each 取代for循环

    使用for_each的好处,相对于手写for循环, for_each把事情拆分成了两部分,一部分是遍历元素,一部分是每个元素要执行的动作. 更易于理解. 针对上述的delete代码,可以参考下面的代码使用for_each修改

    void delSrc(char *pSrc)
    {
        delete[] pSrc;
    }
    
    int main()
    {
        vector<char*> vecCharSrc;
        for (int i = 1; i <= 10; i++)
        {
            char* pChar = new char[i];
            vecCharSrc.push_back(pChar);
        }
    
        std::for_each(vecCharSrc.begin(), vecCharSrc.end(), delSrc);
    }
    

    避免手动释放,利用带计数的智能指针

    void delSrc(char *pSrc)
    {
        delete[] pSrc;
    }
    
    int main()
    {
    
        vector<std::shared_ptr<char>> vecCharSrc;
        for (int i = 1; i <= 10; i++)
        {
            std::shared_ptr<char> pSrc(new char[i], delSrc);
            vecCharSrc.push_back(pSrc);
        }
    }
    

    利用shared_ptr 封装new出来的资源,具有自动释放的能力,比手动写释放资源代码更安全. 即使发生异常,也不会泄露,因为异常会触发各自的析构函数,而shared_ptr对象的析构函数会自动去调用delSrc函数完成资源释放.
    注意,虽然auto_ptr一样有自动的资源释放能力,但是auto_ptr没有计数能力,放到容器里,极易引起误用. 请参考第八条.

    相关文章

      网友评论

          本文标题:Effective STL 第7条

          本文链接:https://www.haomeiwen.com/subject/befrgrtx.html