开发者

Can you change a std::list while iterating through it?

In the following functions, it it entirely possible for the IObserver's Process() function to try to remove itself from the notify list, using the this pointer's DeleteObserver().

This causes hell with the iterators (not surprisingly!), is there a way round this? Or should I be taking a closer look at my design?

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_Observer开发者_StackOverflow中文版List.end(); ++iter)
    {
        (*iter)->Process(this);
    }
}

For example, imagine that the list is a collection of people that subscribe to a magazine and the Process() function is the delivery of a new magazine issue; if the magazines latest issue is awful the subscriber may wish to un-subscribe as a direct result of that issue.


Edit:

Some people in comments corrected me, so I will change this answer. But don't upvote, as it's the commenters' solution, not mine.

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


I don't see why you are not using list::remove here. That seems like a perfect match to me.

For the problem in NotifyObserver I would not let Process do the removing itself but rather let it signal that it wants itself to be removed from the list of observer. Plainly: return a bool from Process to signal and then call list::erase on it. Assign the return value of erase to the current iter.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜