2011-01-18 85 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