Il pattern Visitor è il modo più veloce per eseguire l'identificazione del tipo di parametro del metodo (in pratica un singolo invio su un parametro, non una classe membro) in C++? Potrei conoscere il metodo esatto che voglio invocare su elementi del sottotipo non ancora conosciuto, quindi invariabilmente effettuare una chiamata al metodo virtuale addizionale come V::visit(A *)
in A::accept(V &v) { v.visit(this); }
non è auspicabile.Il pattern Visitor è il modo più veloce per differenziare i tipi di parametri in 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
Mi piacerebbe qualcosa i seguenti, ma con O (1) il costo, che non è per quanto ne so possibile con dynamic_cast <> o typeid() scale funzionalmente equivalenti, dal momento che std::type_info
non può essere una constexpr/commutabile.
// 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;
}
Quali sono le mie opzioni qui? Grazie per il consiglio!
Modifica: Modifica codice di esempio per alimentare i risultati attraverso il campo, in modo tale che non siano necessarie più firme per diversi tipi di metodo. Grazie, Maurizio!
decisione finale: Oltre a non gradire il costo obbligatoria invio doppio del modello Visitatore, ho anche voluto evitare la pesantezza dell'interfaccia di sovraccarico foo()
, ma non credo che ci sia un disegno pulito noto a Fai questo. Ho finito per fare solo drastici sovraccarichi statici e l'ho chiamato un giorno. Ad ogni modo, il mio voler incapsulare il sovraccarico all'interno di una funzione è probabilmente un obiettivo discutibile al meglio. Grazie, Maurice per la risposta.
per i lettori dopo C++ 11: dai un'occhiata alla libreria Yorel Multimethod (che ora è in Boost) –