Bonjour,
Quelques sujets parlant du design pattern visiteur et du double-dispatch on ravivé en moi une ancienne question qui sommeillait.
J'ai deux classes mères :
- Visitable dont chaque filles définie une méthode :
- Visiteur qui défini pour chaque type de Visitable une méthode :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 virtual void visiteMoi(Visiteur & v) { v.visite(*this); }
C'est génial, j'ai juste à hériter de Visiteur et de redéfinir quelques méthodes pour visiter n'importe quel Visitable.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 virtual void visite(Visitable &) { std::cerr << "visitable" << std::endl; } void visite(VisitableFille1 &) { std::cerr << "visitableFille1" << std::endl; }
Tout content, je fais une petite bibliothèque, je la publie...
Et un beau jour, un utilisateur de ma bibliothèque peut me contacter et me dire :
Or pour faire ceci, il n'a que deux solutions :Tu est bien gentil Neckara, mais moi je veux créer une nouvelle classe fille de Visitable et effectuer des traitements spécifiques avec les Visiteur que j'aurais créé
- réécrire la classe Visiteur pour inclure ses méthodes de traitements.
- créer sa propre visite spécialisé (avec VisiteurPerso et VisitablePerso qui sont plus ou moins une copie de Visiteur et de Visitable) qu'on utilisera après avoir effectué la première visite et s'être aperçut qu'on visite des classes créés par l'utilisateur. Pour cela on fait hériter chaque Visiteur créé de Visiteur et de de VisiteurPerso et chaque Visitable créé de VirtualVisitablePerso et de VisitablePerso en n'oubliant pas d'inclure un class VirtualVisitablePerso : public Visitable{ virtual void visiteMoi(Visiteur &)=0;} à la bibliothèque.
Je me demandais s'il n'existait justement pas d'autres solutions/astuces pour éviter ce problème.
Comme faire une sorte de "double double-dispatch" où il suffierait juste de créer sa classe et de définir uniquement les méthodes pour les Types où nous voulons un traitement particulier exemple :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 class Visiteur { public : virtual void visite(Visitable &); } class VisiteurFils : public Visiteur { public : virtual void visite(Visitable &); virtual void visite(VisitableFils &); }
Partager