|
I function pointers (puntatori a funzione, in italiano), contengono
l'indirizzo di una funzione che verrà chiamata attraverso
il puntatore stesso.
Vediamo in dettaglio come funzionano:
//Dichiarazione di
un function ptr
void (*fptr)();
Similmente possono essere dichiarati fptr con return values e parametri,
ad es bool (*fptrMyFunc)(int,int);
Per assegnare una funzione al fptr si usa l'indirizzo della funzione
da assegnare:
// Assegniamo a fptr
la funzione Draw()
// Draw() deve essere stata dichiarata in precedenza come void Draw()
// Ai fptr possono infatti essere assegnate solo funzioni che ritornano
lo stesso tipo
// e con lo stesso tipo e numero di parametri, altrimenti verrà
generato un errore
// al momento della compilazione.
fptr = Draw; // notare che Draw è l'indirizzo
della funzione Draw()
Ora se si chiama fptr durante l'esecuzione del programma verrà
eseguita la funzione che è stata assegnata:
// Eseguiamo Draw()
attraverso fptr
fptr();
Attenzione che in caso il puntatore sia NULL (non gli sia stato
assegnato alcuna funzione), verrà generato un errore run-time(al
momento dell'esecuzione).
La forma fptr() può essere scritta anche come (*fptr)().
I puntatori a funzione possono essere molto utili in alcune situazioni.
Poniamo ad esempio il seguente codice in cui a seconda dello stato
in cui ci troviamo, disegniamo lo schermo in maniera diversa:
switch(state)
{
case GAME:
RenderGame();
break;
case MENU:
RenderMenu();
break;
case CREDITS:
RenderCredits();
break;
}
Per migliorare velocità ed aspetto del codice si può
usare un array di function pointers:
const int
STATES_NUMBER = 3;
// Creiamo fptr
void (*fptrRender[STATES_NUMBER]) ();
// Assegniamo function
ptrs notare la mancanza di (), dato che ci serve l'indirizzo della
funzione
fptrRender[GAME]= RenderGame;
fptrRender[MENU]= RenderMenu;
fptrRender[CREDITS]= RenderCredits;
Sostituiamo poi nel loop principale la struttura switch-case con
la seguente istruzione, che provvede a chiamare la funzione adeguata
a seconda dello stato in cui ci troviamo:
// Disegna schermo
a seconda stato attuale
// veloce e semplice
fptrRender[state]();
Un' ultima cosa prima di chiudere: se volete creare un puntatore
ad funzione di una classe ci sono alcune complicazioni, potete leggere
l'articolo qui.
|