effective stl 第33条:对包含指针的容器使用remove这一类算法时要特别小心

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

class Widget
{
public:
    Widget();
    ~Widget();
    bool isCertified() const{};//该Widget是否已被验证过
private:

};

Widget::Widget()
{
}

Widget::~Widget()
{
}

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

    //做了一系列工作之后,假设要剔除那些未被验证通过的对象
    v.erase(remove_if(v.begin(), v.end(), notl(mem_fun(&Widget::isCertified))));

    return 0;
}

删除容器的指针并不能删除该指针指向的对象。

假设在remove_if调用之前V的布局如下:

这里写图片描述
在调用remove_if之后:

这里写图片描述

一旦remove_if和erase都返回之后:
这里写图片描述

这使得资源泄露更加明显,因此:当容器中存放的是指向动态分配的对象的指针的时候,应该避免使用remove和类似的算法(remove_if和unique),很多情况下,你会发现partition是不错的选择。

如果无法避免使用remove,那么在使用erase-remove算法之前,先把那些指向未被验证过的WIdget的指针删除置空,然后清楚该容器中所有的空指针。

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

class Widget
{
public:
    Widget();
    ~Widget();
    bool isCertified() const{ return false; };//该Widget是否已被验证过
private:

};

Widget::Widget()
{
}

Widget::~Widget()
{
}

void delAndNullifyUncertified(Widget*& pWidget)
{
    if (!pWidget->isCertified())
    {
        delete pWidget;//删除该指针,并把它置空
        pWidget = 0;
    }
}

int main()
{
    vector<Widget*> v;
    for (int i = 0; i < 10; i++)
    {
        v.push_back(new Widget);
    }
    //将所有指向未被验证的Widget对象的指针删除并置空
    for_each(v.begin(), v.end(), delAndNullifyUncertified);
    //删除v中的孔指针:必须将0转换为一个指针,这样C++才能正确推断出remove第三个参数的类型
    v.erase(remove(v.begin(), v.end(), static_cast<Widget*>(0)), v.end());

    return 0;
}

当然这种做法的前提是,你不希望该向量中保留任何空指针。如果你希望它保留空指针,可能只好自己写循环来删除那些满足条件的指针。当你删除一个容器并从该容器中删除元素的时候,有一些微妙的细节值得注意。可以看下第9条的内容。

如果容器中存放的不是普通的指针,而是具有引用计数功能的智能指针,那么与remove相关的困难就不存在了,可以直接使用erase-remove习惯用法。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值