Le modèle de visiteur est-il le moyen le plus rapide d'effectuer l'identification du type de paramètre de méthode (envoi direct sur un paramètre, pas la classe d'un membre) en C++? Je pourrais connaître la (les) méthode (s) exacte (s) que je veux invoquer sur des éléments du sous-type pas encore connu, donc invariablement faire un appel de méthode virtuelle supplémentaire comme V::visit(A *)
dans A::accept(V &v) { v.visit(this); }
est indésirable.Le modèle de visiteur est-il le moyen le plus rapide de différencier les types de paramètres en C++?
// Is the Visitor pattern recommended here? (E inherits D inherits B.)
class Foo {
public:
virtual void visit(B *) { result = 3; }
virtual void visit(D *) { result = 4; }
virtual void visit(E *) { result = 5; }
private:
int result;
}; // class Foo
// Need to add generic interface to B and its children ...
class B {
public:
virtual void accept(class Foo &f) { f.visit(this); }
}; // class B
Je voudrais quelque chose fonctionnellement équivalent aux échelles suivantes, mais avec O (1) coût, ce qui est impossible avec AFAIK dynamic_cast <> ou typeid(), puisque std::type_info
ne peut pas être un constexpr/commutable.
// O(n) search cost might get nasty with bigger hierarchies.
int foo(B *b) {
if (typeid(b) == typeid(B *)) { return 1; }
if (typeid(b) == typeid(D *)) { return 2; }
if (typeid(b) == typeid(E *)) { return 3; }
return -1;
}
Quelles sont mes options ici? Merci pour le conseil!
Édition: Modification de l'exemple de code pour acheminer les résultats via le champ, de sorte que plusieurs signatures ne soient pas nécessaires pour différents types de méthode. Merci, Maurice!
Décision finale: En plus de ne pas aimer le coût double expédition obligatoire du motif des visiteurs, je voulais aussi éviter le ballonnement d'interface de surcharge foo()
, mais je ne pense pas qu'il y ait un modèle propre connu fais ceci. J'ai fini par faire des surcharges statiques et je l'ai appelé un jour. Quoi qu'il en soit, mon désir d'encapsuler une surcharge dans une fonction est probablement un objectif discutable au mieux. Merci, Maurice pour la réponse.
pour les lecteurs après C++ 11: jetez un oeil à la bibliothèque Yorel Multimethod (qui est dans Boost maintenant) –