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
.
精彩评论