STL : List使用時應注意的問題

這篇文章所述只是本人遇到的問題,僅供參考。ios

#include<list>
#include<iostream>

using namespace std;

class Foo
{
public:
    Foo(int i) {m_iData = i;}
    void setData(int i ) {m_iData = i;}
    int GetData() {return m_iData;}
private:
    int m_iData;
};
// 爲了提升可讀性,定義容器和迭代器的名字
typedef list<Foo*> FooList;
typedef FooList::iterator FooListItor;

void main()
{
    FooList c; // 建立一個鏈表容器

//將三個不一樣的元素填入鏈表中
    c.push_back(new Foo(1));
    c.push_back(new Foo(2));
    c.push_back(new Foo(3));
//迭代遍歷鏈表
    for(FooListItor itor = c.begin();itor != c.end();)
    {
        if((*itor)->GetData() == 2)
        {
            delete (*itor);
            itor = c.erase(itor);
        }
        else
            ++itor;
    }

//確保全部的對象被刪除,鏈表不會自動完成該項任務
for(FooListItor itor2 = c.begin(); itor2 != end();++itor2)
    delete (*itor2);
}    

 

使用指針指向動態分配內存的結構或對象時,有幾件事情須要注意。算法

1. 你要負責在使用完對象後釋放全部分配的內存。容器並不知道將使用何種類型,因此它們不可能幫你自動釋放內存。安全

2. 許多運算可能會失敗,這是由於它們直接對對象或結構的指針進行操做,而不是對對象或結構自己。好比鏈表的sort()函數,它使用<運算符來比較值並以此結果進行排序。就算運算符對類Foo是合法的,但鏈表的排序還是按照指針的實際值而不是對象中數據的值。於是有必要設計本身的比較運算符,在比較以前先對指針解引用。函數

3.記住,複製容器時,複製的僅僅是指針而不是對象。若是產生了重複的指針,將極難肯定哪個對象須要刪除。解決辦法是使用智能指針(smart pointer),或避開容器間複製元素的STL的例程或算法。spa

4.注意,在迭代遍歷鏈表的時候,從鏈表中刪除元素要很是當心。由於刪除當前指向的元素將致使迭代器失效,因此你必須確保正確使用erase()函數的返回值,它是這個函數將檢索出的容器中的下一個合法位置,經過將這個返回值分配給老的迭代器,咱們就跳過了非法位置。可是這又給咱們帶來了新的問題。當for循環在循環結束處試圖對迭代器遞增,因爲咱們已經用erase()將迭代器遞增到了下一個位置,所以就會出現問題。爲了解決這個問題,咱們將遞增運算從for循環體移到了循環中的條件選擇語句內,在元素沒有刪除時才進行遞增。(通常來講,最好使用算法從容器中刪除元素,而不是手工迭代來作,如算法remove_if()就能安全有效地進行該項操做)。設計

相關文章
相關標籤/搜索