PDA

Visualizza la versione completa : [C++] Puntatore ad un membro


cadue
01-11-2007, 14:49
salve! sto facendo alcune prove per inserire delle callbacks nel mio progetto, ma ho un problema:



BasicEnemy::BasicEnemy(){
void(*funz)();
funz = &BasicEnemy::PlayerCollision;
}


l'errore è il seguente:
error C2440: '=': impossibile convertire da 'void (__thiscall BasicEnemy::* )(void)' a 'void (__cdecl *)(void)'
void PlayerCollision() è un membro pubblico della classe BasicEnemy. Come posso fare a far puntare "funz" al membro "void PlayerCollision()"? Grazie!

MacApp
01-11-2007, 15:29
Originariamente inviato da cadue
salve! sto facendo alcune prove per inserire delle callbacks nel mio progetto, ma ho un problema:



BasicEnemy::BasicEnemy(){
void(*funz)();
funz = &BasicEnemy::PlayerCollision;
}


l'errore è il seguente:
error C2440: '=': impossibile convertire da 'void (__thiscall BasicEnemy::* )(void)' a 'void (__cdecl *)(void)'
void PlayerCollision() è un membro pubblico della classe BasicEnemy. Come posso fare a far puntare "funz" al membro "void PlayerCollision()"? Grazie!

PlayerCollision non è di tipo void(*funz)(), perché essendo una funzione membro (non static) implicitamente tra i suoi argomenti ha anche l'indirizzo di un'istanza di BasicEnemy.

Per giocare coi puntatori membro, il C++ fornisce la funzione template std::mem_fun ed il tipo template std::mem_fun_t, ad esempio:


//
// Compiled and tested with:
// i686-apple-darwin8-gcc-4.0.1 (GCC) 4.0.1 (Apple Computer, Inc. build 5367)
//

#include <iostream>
#include <functional>

namespace ig{
class BasicEnemy{
public:
BasicEnemy (void);
void PlayerCollision (void);
};
}

namespace ig{
BasicEnemy::BasicEnemy (){
std::mem_fun_t <void, BasicEnemy> aMemFunPtr = std::mem_fun (&BasicEnemy::PlayerCollision);
aMemFunPtr (this); // Automagically call this->PlayerCollision ();
}
void BasicEnemy::PlayerCollision (){
std::cout << "Hello from BasicEnemy::PlayerCollision" << std::endl;
}
}

int main (int argc, char * const argv[]) {
ig::BasicEnemy aBasicEnemy; // inside is calling PlayerCollision

// again, calling PlayerCollision:
std::mem_fun_t <void, ig::BasicEnemy> aMemFunPtr = std::mem_fun (&ig::BasicEnemy::PlayerCollision);
aMemFunPtr (&aBasicEnemy); // Automagically call aBasicEnemy.PlayerCollision ();
return 0;
}


Osserva che le variabili locali aMemPtr definite nel costruttore ed in main, sono dei funtori associati al metodo ig::BasicEnemy::PlayerCollision.

cadue
01-11-2007, 19:03
urca...veramente più complesso di quanto immaginassi! grazie per il codice, mi sarà senz'altro utile!

Loading