std::vector : Suppression pendant une iteration
Bonjour à tous,
Pour implémenter le pattern Observer, je propose une interface d'écoute.
Code:
1 2 3 4 5 6
|
class IListener
{
public:
virtual void OnEvt();
} |
Ensuite, dans la classe pouvant lancer cet évennement, j'ai un vector d'objets implémentant cette interface, et je propose de s'inscrire ou se désinscrire à cet evennement.
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
class MaClass
{
public:
void AddListener(IListener* pListener);
void RemoveListener(IListener* pListener);
private:
void NotifyEvt();
std::vector<IListener*> m_vecListeners;
}
void MaClass::NotifyEvt()
{
for(std::vector<IListener*>::iterator it = m_vecListeners.begin(); it != m_vecListeners.end(); ++it)
{
(*it)->OnEvt();
}
} |
Mon soucis est que sur réception de l'évennement, certains écouteurs peuvent ne plus avoir besoin d'écouter. Donc ils font
Code:
1 2
|
m_maClass.RemoveListener(this); |
Ce qui provoque la suppression d'un élément dans le vector alors que je suis en train d'iterrer dessus.
J'ai essayer de mettre un iterator en tant que membre de ma classe, comme ceci :
Code:
1 2 3 4
|
private:
std::vector<IListener*> m_vecListeners;
std::vector<IListener*>::iterator m_CurIt; |
Puis de l'initialiser à begin() en début de notification, et, lors du "erase" sur le vector, de lui affecter le retour.
Code:
1 2
|
m_CurIt = m_vecListeners.erase(std::find(m_vecListeners.begin(), m_vecListeners.end(), pListener)); |
Mais dans la boucle de notification, si m_CurIt a été réaffecté (donc à l'élément suivant), il ne faut pas que je l'incrémente, sinon je l'incrémente, mais il faut également gérer le cas où il est passé à m_vecListeners.end() etc...
Bref, j'arrive à quelque chose d'étrangement compliqué et je voudrai savoir s'il n'y avait pas un moyen plus simple pour gérer ce genre de chose ?
Merci beaucoup,
A bientôt