dna_programmer ha scritto:
in pratica MouseDown cos'è un array che contiene tutte le funzioni che verranno chiamate?
Si. E per essere precisi diciamo che non si tratta di funzioni ma di metodi di oggetti (o meglio delegati), cosi introduciamo il secondo argomemto.
dna_programmer ha scritto:
so cosa sono più o meno i puntatori a funzione,ma i puntatori a metodi è la prima volta che li sento(non dovrebbe essere più o meno la stessa cosa di quelli a funzione ?)
Ho scritto puntatori a metodo ma a essere precisi dovevo dire 'delegati'.
Tanto per comiciare in NetFramework non puoi scrivere una funzione, puoi solo scrivere metodi, tutto deve stare dentro una classe (questo l' ha preso da Java). Quindi per parlare di puntatori a funzione uso il C++.
Nel caso dei puntatori a funzione supponi di avere due funzioni, una scrive 'ciao' e l' altra 'hello', puoi assegnare l' indirizzo di una funzione ad un puntatore e poi richiamarla attraverso di esso:
#include <iostream>
using namespace std;
void FunctionCiao()
{
cout << "Ciao";
}
void FunctionHello()
{
cout << "Hello";
}
int main()
{
void (*f)() = FunctionCiao;
f(); // scrive Ciao
f = FunctionHello;
f(); // scrive Hello
int n = sizeof(f);
return 0;
}
Il puntatore f contiene l' indirizzo della funzione, la funzione è un blocco di codice che si trova in un certo posto nella memoria, per eseguirla basta spostare il program counter del programma a quella posizione (ho semplificato ma è cosi).
Se esamini col debugger la variable f vedrai che contiene un numero e che la sua dimensione è di 4 byte.
Ora invece supponi di avere una classe 'Persona' che ha un metodo che scrive il suo nome.
class Persona
{
public:
string nome;
Persona(string nome)
{
this->nome = nome;
}
void Scrivi()
{
cout << nome.c_str();
}
};
Non puoi fare la stessa cosa, cioè non puoi semplicemente richiamare la funzione Scrivi (cosa scrive? Mario, Antonio Piero?) devi prima creare un oggetto persona e poi richiamare la funzione Scrivi passandole l' indirizzo dell'oggetto (il famoso this). Quindi ti servono due informazioni, l' indirizzo del metodo e l' indirizzo dell' oggetto. Una entità che racchiude queste informazioni viene chiamato 'Delegato'.
Nello standard del C++ non esistono i delegati (mi pare), però esistono i puntatori a metodo che sono una cosa leggermente diversa e si usano in questo modo:
Persona mario("Mario");
Persona luigi("Luigi");
void (Persona::* m) () = &Persona::Scrivi;
(mario.*m)();
Ma di questo non ne parliamo. Se ci fosse una classe delegato (esisterà sicuramente qualcosa, per ora invento) si potrebbe usare in questo modo:
Delegate d = mario.Scrivi();
d(); // scrive Mario;
d = luigi.Scrivi();
d(); // scrive Luigi;
Riassumendo, un puntatore a funzione contiene l' indirizzo di una funzione (è un numero di 4 byte), un delegato invece contiene due informazioni, l' indirizzo di una funzione e l' indirizzo di un oggetto.