2011-01-18 86 views
0

我有一個類,它有一個名爲_Emails的成員。它的類型是set<PEmail*>。當我在成員函數中,並運行以下代碼時,它將按預期工作:C++在類中設置迭代器

for(set<PEmail*>::iterator it=this->_Emails->begin(); it!=this->_Emails->end(); ++it) 
    { 
    cout << "Email: " << (*it)->getEmail() << endl; 
    } 

也就是說,它會生成一個電子郵件地址列表。現在,我希望能夠隨着課程的增長而添加到這個集合中,而不會失去我最後一次迭代的位置。我試圖讓我班的另一名成員名爲_EmailItr,其類型爲set<PEmail*>::iterator。我初始化它在我的構造,我_Emails之後,就像這樣:

this->_Emails = new set<PEmail*>; 
this->_EmailItr = this->_Emails->begin(); 

然後,試圖for循環做類似:

// send the max queue amount, or until there are no more emails           
for(int i=0; i<this->_QueueSize || i==_Emails->size(); ++i) 
    { 
    cout << "i: " << i << endl; 
    cout << "QueueSize: " << this->_QueueSize << endl; 
    cout << "Emails: " << this->_Emails->size() << endl; 

    cout << (*_EmailItr)->getEmail() << endl; 
    } 

我得到以下輸出:

i: 0 
QueueSize: 2 
Emails: 2 
Segmentation fault 

什麼給?我是否嘗試以不正確的方式使用迭代器?

+1

以下劃線和大寫字母開頭的標識符被保留用於所有目的的實現。我建議改變這些標識符並在出現真正奇怪的錯誤之前擺脫下劃線資本的習慣。 – 2011-01-18 21:21:58

+1

作爲一個方面說明,如果你想使用一個有序的容器(例如`std :: set`,`set:map`及其多對等體)來存儲指向對象的指針(`set `),而不是對象的副本,你需要提供一個嚴格的弱順序謂詞否則或你在一些驚喜... – 2011-01-18 21:27:48

回答

4

當你創建std::map之後得到this->_Emails->begin(),你得到的迭代器結束迭代(因爲有在std::map沒有元素,它的大小是零和begin() == end())。您不能取消引用或增加結束迭代器。它並沒有指出「容器的開始;」它指向「當前在開始的元素」,或者如果容器是空的,它將返回結束迭代器。

(在一個不相關的音符,它看起來像你正在做太多的動態分配。你爲什麼要動態地創建std::set對象(使用new)?爲什麼不只是有一個std::set作爲類的成員嗎?)

1

STL set在迭代過程中插入新元素時表現良好。特別是,如果您在添加新元素的同時迭代set,則不會「迷失」自己的位置;你的迭代器將保持有效,它會看到添加或刪除的任何新元素。我不完全確定你的用例在這裏,但我不認爲你需要在這裏介紹的所有添加的機器。只使用沒有任何裝飾的老式迭代器應該可以工作得很好。

2

當您首次創建集_Emails,然後將_EmailItr設置爲_Emails->begin()時,迭代器不指向任何內容。實際上,它指向_Emails->end(),因爲當該集合爲空時,begin()end()是相同的。

因此,稍後嘗試取消引用指向end()的迭代器,這是未定義的行爲並導致崩潰。

您似乎認爲迭代器實際上以某種方式在後臺添加新對象到列表中時「更新」。不是。它總是指向end()。您需要將設置爲_Emails->begin(),然後將元素插入集合中。


此外,與您的問題無關,但:是否有某些原因需要在堆上分配_Emails