PDA

Visualizza la versione completa : [C++] Passaggio metodo classe come funzione handler


MrX87
28-05-2014, 18:21
Ciao a tutti, ho un problema con un pezzo di codice su C++ in particolare ho un metodo di una classe che prende come parametro un indirizzo di una funzione e la usa come handler in caso si verifica un determinato evento; adesso io volevo passare a questa funzione non un indirizzo di una funzione ma di un metodo di una classe ovvero, faccio un esempio con del codice:

Classe Receiver


class Receiver {


public:
Receiver();
~Receiver();
void StartRecvMessages();


private;
void message_handler( MyObj& obj );

};



File Receiver.cpp


void msg_handler ( MyObj& obj );


void Receiver::StartRecvMessages() {
// ...


SocketReceiver r;
MyObj obj;


// in questo modo non compila suppongo perchè devo fare riferimaneto
// in qualche modo al fatto che message_handler è un metodo della classe Receiver
// ma in che modo?
r.async_receive<MyObj>( &message_handler );


// neppure se metto in questo modo che avrebbe più senso, funziona
r.async_receive<MyObj>( &(Receiver::message_handler) );


// mentre così funziona
r.async_receive<MyObj>( &msg_handler );


//...


}


void Receiver::message_handler( MyObj& obj ) {
//do somethings
}


void msg_handler ( MyObj& obj ) {
//do somethings
}



Ci potrebbero essere degli errori perchè ho scritto il codice semplificato solo per fare un esempio e non è compilabile.
Purtroppo la parte del metodo async_receive ha solo quel parametro ed è una funzione di una libreria che devo usare, quindi non posso aggiungergli parametri.

Qualcuno che ha una dritta?
grazie mille ragazzi

Scara95
30-05-2014, 15:10
Un metodo non appartiene alla classe, ma all'oggetto istanziato.
A te serve un metodo statico (static method).
Cerca su google.

MrX87
30-05-2014, 16:32
Un metodo non appartiene alla classe, ma all'oggetto istanziato.
A te serve un metodo statico (static method).
Cerca su google.
Ok...intendi una cosa simile quindi...modificando il metodo della classe Receiver così



static void message_handler ( MyObj& obj );


di conseguenza anche l'implementazione nella classe .cpp



static void Receiver::message_handler ( MyObj& obj ) {

}


e la chiamata alla async_recv come sarebbe??

Avevo anche provato in questo modo ma, forse sbagliando non sono riuscito a far funzionare nulla.

oregon
30-05-2014, 16:33
Metodo di una funzione ?

Sì utilizza un metodo statico e funziona ...

MrX87
03-06-2014, 16:50
Metodo di una funzione ?

Sì utilizza un metodo statico e funziona ...

Okay usando un metodo statico effettivamente funziona, però....in un metodo statico non ho modo di fare riferimento ai membri della classe, quindi effettivamente non ci guadagno molto a farlo!?

Scara95
03-06-2014, 19:17
Okay usando un metodo statico effettivamente funziona, però....in un metodo statico non ho modo di fare riferimento ai membri della classe, quindi effettivamente non ci guadagno molto a farlo!?

Puoi usare qualsiasi membro static.

MItaly
03-06-2014, 21:14
In C++ un puntatore a funzione può solo puntare o ad una funzione libera o ad un membro static (che all'atto pratico è sostanzialmente una funzione libera in un namespace particolare); non puoi passare dentro un puntatore a funzione un puntatore ad un metodo di istanza, dato che questo richiederebbe un puntatore a funzione più un puntatore all'istanza su cui dovrebbe operare, e le due cose ovviamente non ci stanno nello spazio destinato ad un solo puntatore a funzione.

Se controlli l'interfaccia del callback, da C++11 puoi specificare che vuoi ricevere un oggetto std::function, che, tramite type erasure, consente di portarsi dentro qualunque oggetto "chiamabile" (puntatore a funzione, funzione lambda, metodo d'istanza bindato ad un'istanza specifica, functore, ...). In alternativa, se si tratta di un callback fissato (ad esempio che dipende da una libreria C), normalmente oltre al callback è possibile specificare un dato di "contesto" (normalmente un void *) che viene passato come argomento del callback. In genere questo da lato C++ viene sfruttato per metterci dentro l'istanza su cui operare, per cui passerai come callback un metodo statico che fa il cast del "contesto" al tipo appropriato e ci richiama sopra il metodo che vuoi.

Loading