你可以在迭代时更改std :: list吗?

时间:2011-09-29 13:59:12

标签: c++ std

在以下函数中,IObserver的Process()函数完全有可能尝试使用this指针的DeleteObserver()从通知列表中删除自己。

这会导致迭代器地狱(不出意外!),有没有办法解决这个问题?或者我应该仔细看看我的设计?

void cButtonManager::DeleteObserver(IObserver *observer)
{
    list<IObserver*>::iterator iter;
    for (iter = m_ObserverList.begin(); iter != m_ObserverList.end(); ++iter)
    {
        if (*iter == observer)
        {
            // Found the specified observer in the list, delete it
            m_ObserverList.erase(iter);
            return;
        }
    }
}

void cButtonManager::NotifyObservers(void)
{
    list<IObserver*>::iterator iter;
    for (iter = m_ObserverList.begin(); iter != m_ObserverList.end(); ++iter)
    {
        (*iter)->Process(this);
    }
}

例如,假设该列表是订阅杂志的人的集合,Process()功能是新杂志的发行;如果杂志最新的问题很糟糕,订阅者可能希望取消订阅作为该问题的直接结果。

2 个答案:

答案 0 :(得分:3)

修改

有些人在评论中纠正了我,所以我会改变这个答案。但是不要赞成,因为这是评论者的解决方案,而不是我的解决方案。

(*iter++)->Process();

答案 1 :(得分:1)

我不明白你为什么不在这里使用list::remove。这似乎与我完美匹配。

对于NotifyObserver中的问题,我不会让Process执行删除本身,而是让它发出信号表明它希望自己从观察者列表中删除。显而易见:从Process返回一个bool信号,然后在其上调用list::erase。将erase的返回值分配给当前iter