Al nome di una funzione viene normalmente associato l’indirizzo del suo punto di ingresso.
Pertanto il nome di una funzione può essere visto come l’indirizzo della funzione e cioè come puntatore (costante) alla funzione stessa.
E’ possibile fare riferimento ad una funzione per mezzo di un puntatore a cui viene assegnato il valore del punto di ingresso ad una funzione.
Pertanto tale puntatore può essere utilizzato per attivare diverse funzioni a seconda del suo valore corrente.
Il linguaggio C++ (e il C) prevede i puntatori a funzione.
I puntatori a funzione sono utili soprattutto per scegliere la funzione da chiamare fra diverse funzioni possibili, in dipendenza da valori assunti da variabili del programma (in questo caso quindi la scelta non può essere effettuata a tempo di compilazione ma solo a tempo di esecuzione).
Gli indirizzi delle funzioni da chiamare vengono risolti a tempo di esecuzione _(late binding) e non a tempo di compilazione (early binding).
Un puntatore a funzione è dichiarato come segue:
T(*nomeptr)(T1, T2, … Tn);
Ad esempio:
float (*Pf)(int, char*);
dove
float è il tipo ritornatao della funzione
int, char* sono i tipi dei paramentri formali
La dichiarazione
float (*Pf)(int , char* );
dichiara un puntatore a funzione Pf che restituisce un valore reale ed ha due argomenti: il primo é di tipo intero, il secondo é un puntatore a char.
Le parentesi intorno al nome del puntatore a funzione sono necessarie!
In assenza delle parentesi la dichiarazione sarebbe interpretata dal compilatore come la dichiarazione di una funzione il cui tipo di ritorno è un puntatore a float.
La funzione usata per assegnare (o inizializzare) il puntatore a funzione deve essere stata precedentemente dichiarata: la sua dichiarazione deve corrispondere alla dichiarazione del puntatore (tipo del valore di ritorno e lista dei parametri formali).
Per chiamare la funzione mediante il puntatore:
(*Pf)(5,”Hello World”);
… ma anche:
Pf(5,”Hello World”);
E’ possibile definire array i cui elementi sono di tipo puntatore a funzione. Questa soluzione è utile se in un programma si devono attivare funzioni diverse a seconda del valore assunto da un indice.
E’ possibile specificare un puntatore a funzione come parametro di scambio. Questa soluzione è utile per passare ad una funzione f il nome di una funzione g sulla quale f debba operare, in modo da rendere la funzione f indipendente da una specifica definizione della funzione g.
T (*Pf) (…)
Pf è un puntatore ad una funzione che ritorna un valore di tipo T e ha la lista di parametri formali specificati tra le parentesi tonde a sinistra.
typedef T (*Pf) (…)
Pf è il nome di un tipo puntatore a funzione.
Pf ptr;
ptr è un puntatore a funzione con le caratteristiche di cui al punto 1.
1. Strutture e typedef. Record in C/C++: Concetti Base
4. Puntatori a tipi di dato strutturati. Allocazione Dinamica
5. Puntatori: aspetti avanzati
7. Asserzioni
8. Gestione delle eccezioni. Concetti base
9. Programmazione modulare: concetti base
10. Programmazione Modulare: Meccanismi e Strumenti a supporto in C/C++
12. Esercitazione: Strutture Dati Pila e Coda
13. Esercitazione. Strutture Dati: Lista Concatenata
14. Meccanismi di Incapsulamento in C++ Namespaces
15. Programmazione orientata agli oggetti. Introduzione
Da C++ a UML
Capitolo 9, da par. 9.1 a 9.5
puntatori per accesso alla linea di comando: esempio 9.3
Funzioni che ritornano puntatori: par. 9.4, 9.5
Puntatori a void: par. 9.6
Puntatori a funzioni: par.9.7, 9.8, 9.9