Newsgroup: it.comp.lang.c++
Titolo: Invocare un metodo

Salve a tutti, vorrei porvi un quesito che da molti giorni mi affligge.
E' possibile in C++ invocare un metodo di una classe, avendo il suo nome in
una stringa ?
Se faccio una serie di if funziona, ma e' una cosa inguardabile.



Sono troppo curioso di vedere perchč ti serve... puoi postare il pezzo
di codice???
Luc.

 ha scritto nel messaggio
news:xUB07.24768$_F1.3...@news2.tin.it...

Utilizza un oggetto COM!

 ha scritto nel messaggio
news:xUB07.24768$_F1.3...@news2.tin.it...

Il collo di bottiglia è il tempo necessario a confrontare le stringhe.
Se non hai grossi problemi di velocità la serie di if / else if ... / else è
la più semplice da implementare.
Se invece i casi da verificare sono molti , la velocità è un problema e le
funzioni hanno gli stessi parametri (...per chi non ama i void*  ;-) puoi
usare una tecnica di queso tipo :
1) Se hai dimestichezza con la libreria standard puoi usare un oggetto
map<stringa, puntatore a funzione>
2) Se no definisci una struttura del tipo
struct coppia {
   puntatore a funzione; (o puntatore a membro funzione)
   puntatore a char* (stringa);
   bool operator <(const coppia& c) const;  // per algoritmo di ordinamento
stringhe se non ti crei l' array "a mano"
};
poi crei un array ordinato di questa struttura.
All' interno di questo array ordinato esegui una ricerca con un numero di
confronti logaritmico.
Ti risparmio gli alberi binari bilanciati.
----
Sergio Bianchi



Ecco un'ideuccia che ho tradotto in codice giusto per vedere se veniva
fuori qualcosa di interessante. Non so se abbia una qualche valida e
ragionevole applicazione, ma tant'è...
 #include <string>
 #include <map>
 #include <iostream>
 template< class T, class Result, class Arg >
 struct bound_mem_func_1
 {	
    typedef Result (T::* mem_func_type )(Arg);
    T*	       this_;
    mem_func_type	pm_;
 
    bound_mem_func_1( T* p, mem_func_type pm ) : this_(p), pm_(pm) { }
    Result operator()( Arg a ) { return (this_->*pm_)(a); }
 };
 class MyClass
 {
  typedef bound_mem_func_1<MyClass,int,int>        bound_mem_func_type ;
  typedef std::map<std::string, 
	typename bound_mem_func_type::mem_func_type> mem_func_map_type;
  mem_func_map_type		map_;
  public:
 
  // i seguenti membri sono di tipo bound_mem_func_type::mem_func_type 
  int mem_func_1( int i ) { cerr << "mem_func_1"<< endl; return i ; };
  int mem_func_2( int i ) { cerr << "mem_func_2" << endl; return i ; };
  int mem_func_3( int i ) { cerr << "mem_func_3" << endl; return i ; };
  int mem_func_4( int i ) { cerr << "mem_func_4" << endl;return i ; };
  MyClass()
  {
    map_["mem_func_1"] = &mem_func_1;
    map_["mem_func_2"] = &mem_func_2;
    map_["mem_func_3"] = &mem_func_3;
    map_["mem_func_4"] = &mem_func_4;
  }
  bound_mem_func_type	by_name( const std::string& str ) 
  { return  bound_mem_func_type( this, map_[ str ] ); }
 };
Esempio...
int main()
{
   MyClass		p;
  // invoco direttamente...
   p.by_name("mem_func_2")(2);	
  // lo salvo in una variabile...
   MyClass::bound_mem_func_type mem = p.by_name("mem_func_2");
  // ...e lo invoco separatamente
   mem(3);
}
Una "interessante" implicazione di questa idea è la possibilità di creare
mappe o vettori (o quel che vuoi) di funzioni membro diverse legate a
oggetti diversi:
  MyClass		a;
  MyClass		b;
  MyClass		c;
  std::vector< MyClass::bound_mem_func_type>	v;
  v.push_back( a.by_name("mem_func_1") ); // a & mem_func_1
  v.push_back( b.by_name("mem_func_2") ); // b & mem_func_2
  v.push_back( c.by_name("mem_func_3") ); // c & mem_func_3
  v[0](2);
  v[1](2);
  v[2](2);
 
 
Max

 ha scritto nel messaggio
news:xUB07.24768$_F1.3...@news2.tin.it...


 ma se non conosco inizialmente il nome della classe, come faccio ?
Non puoi. Un puntatore a membro di A e' diverso da un puntatore a membro di B.
Non sono due puntatori uguali ma con VALORE diverso. Sono proprio due tipi
completamente diversi.
--
Andrea Ferro
---------
Brainbench C++ Master. Scored higher than 97% of previous takers
Scores: Overall 4.46, Conceptual 5.0, Problem-Solving 5.0
More info 
http://www.brainbench.com/transcript.jsp?pid=2522556

 ha scritto nel messaggio
news:B5X07.31783$_F1.3...@news2.tin.it...

Una cosa del tipo
   template class<T>
   struct fpointer {
      int (T::* pUMLClass_mem1)(void);
   };
   map<string, fpointer<yourclass> >
  ti permette di scrivere il codice astraendo dal tipo di classe ma devi poi
definirlo ad un certo punto se vuoi compilare.
  Se invece tale scelta deve avvenire a runtime puoi definire una classe
astratta come specifica di interfaccia ed utilizzare le diverse classi
derivate per modificare il comportamento del sistema.
----
Sergio Bianchi