【CPP】從容器中刪除元素

本文內容學習自 Scott Meyers的《Effective C++》“第33條:對包含指針的容器使用remove這一類算法時要特別小心”

remove搭配erase

容器(除了list)中的remove不是真正意義上的刪除。因爲它做不到。
remove僅僅是把想要移動的對象放到容器的後面,不需要替換的元素不斷從後面移動、替換前面需要被刪除的元素。
在這裏插入圖片描述
vector<int>::iterator newEnd( remove(v.begin(), v.end(), 99) );
在這裏插入圖片描述
remove和erase可以實現真正的刪除。

    vector<int> v;
    v.push_back( 1 );
    v.push_back( 2 );
    v.push_back( 3 );
    v.push_back( 99 );
    v.push_back( 5 );
    v.push_back( 99 );
    v.push_back( 7 );
    v.push_back( 8 );
    v.push_back( 9 );
    v.push_back( 99 );

    vector<int>::iterator newEnd( remove( v.begin(), v.end(), 99 ) );
    v.erase( newEnd, v.end() );
    for( auto it: v )
    {
        cout << it << "\t";
    }
    cout << endl;

裝載指針的容器刪除元素

如果容器內部是指針(不包括智能指針),那麼刪除元素就需要仔細,避免內存泄露。
通常需要先釋放指針所指向的內存,然後再刪除元素(指針)
例如:

#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;

class Widget
{
public:
    Widget(const int _value){ value = _value; }
    bool isCertified(){ return value != 0; }
    int GetValue(){ return value; }
private:
    int value;
};

void delUncertified( Widget* &pWidget )
{
    if( !pWidget->isCertified() )
    {
        delete pWidget;
        pWidget = nullptr;
    }
}

int main(int argc, char *argv[])
{
    vector<Widget*> v;
    for( int i = 0; i < 5; ++i )
    {
        v.push_back( new Widget( i ) );
    }
    for_each( v.begin(), v.end(), delUncertified );
    v.erase( remove( v.begin(), v.end(), static_cast<Widget*>(0) ), v.end() );
    for( auto it: v )
    {
        cout << it->GetValue() << "\t";
    }
    cout << endl;
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章