Bonjour à tous,


Pour implémenter le pattern Observer, je propose une interface d'écoute.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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