PDA

Visualizza la versione completa : [c]simulare chiamate di metodo con i puntatori a funzione


chu
16-08-2010, 18:13
Ciao a tutti, devo affrontare un esercizio riguardo questo uso dei puntatori a funzione in c. L'esercizio di partenza consiste nel definire una struttura dati per un punto cartesiano, per un triangolo, un quadrato e un pentagono. Inoltre c'era da definire una struttura(union) che potesse contenere una qualsiasi tra le 2 figure precedenti. Infine l'esercizio chiedeva una funzione perimetro() che ricesse come parametro l'union figura. Io ho definito, rispettivamente, la struttura per il punto, il triangolo, il quadrato, il pentagono come segue:

struct point{
double x;
double y;
};

struct triangolo{
struct point p1;
struct point p2;
struct point p3;
};

struct quadrato{
struct point p1;
struct point p2;
struct point p3;
struct point p4;
};

struct pentagono{
struct point p1;
struct point p2;
struct point p3;
struct point p4;
};

union figura{
struct triangolo t;
struct quadrato q;
struct pentagono p;
};

Ora richiesto nell'esercizio avanzato quanto segue:
"Si modifichi ora quell'esercizio definendo varie funzioni che calcolano il perimetro, una per ogni tipo di figura geometrica considerata, e si aggiunga a figura un puntatore a funzione perimetro che sar inizializzato, per ogni istanza di figura, alla funzione che calcola il perimetro nel modo appropriato per quella particolare figura. In questo modo, data una istanza di figura, sar possibile invocare il "metodo" perimetro() senza sapere a priori di che tipo di figura si tratta."
Ecco, io ho dei problemi ad impostare l'esercizio, in particolare:
1)quella che prima era una union figura ora una struct contenente una union e il puntatore a funzione?
2)Se s cosa prende per parametro?
3)le funzioni per calcolare i perimetri prendono per parametro una struct triangolo, quadrato o pentagono oppure una struct figura?
Per favore aiutatemi perch non ci levo le gambe!!
ps:nel caso non fossi stata chiara i testi degli esercizi sono qui http://margot.di.unipi.it/mediawiki/index.php?title=Esercitazioni#Puntatori_a_funzione _come_metodi

shodan
16-08-2010, 20:16
Leggi questo thread:
http://forum.html.it/forum/showthread.php?threadid=1417665

chu
17-08-2010, 22:07
ciao, grazie per aver risposto prima di tutto! Quindi la soluzione potrebbe essere usare come parametri per la funzione i puntatori void?Ma l'idea di trasformare la union figura in una struct contenente la union corretta o c' uno sbaglio concettuale?

shodan
17-08-2010, 22:46
Forse ho letto male, ma non trovo dove c' scritto di trasformare la union in una struct.
Quello che richiesto di aggiungere un puntatore a funzione che data una specifica istanza della union, consenta di calcolare il perimetro.
Diciamo che dal mio personale punto di vista, una union usata in quel modo sbagliata, visto che nessuno vieta di inserire un triangolo ed estrarre un pentagono. Personalmente avrei usato una struct di figure diverse, ma l'uso della union non sbagliato di per se.

L'uso dei puntatori void obbligato dal momento che non si sa a priori con che figura verr invocata la funzione. Quindi dovendo essere generica, deve poter prendere qualsiasi tipo di parametro. Il problema semmai che ogni singola funzione reale deve adattarsi alla figura reale, ma quale funzione associare alla figura lo decidi tu. E nulla (a livello di compilatore) vieta di usare la funzione perimetro del triangolo su un pentagono, per esempio.

Per quello che ho capito, la cosa diventa (supponendo che la funzione in questione non restituisca nulla):



typedef void (*CalcolaPerimetro)(const void*);

void CalcolaTriangolo(const void*);
void CalcolaQuadrato(const void*);
void CalcolaPentagono(const void*);

union figura{
struct triangolo t;
struct quadrato q;
struct pentagono p;
CalcolaPerimetro cp;
};

union figura figuraTriangolo;
figuraTriangolo.cp = CalcolaTriangolo; // ora posso solo usare un triangolo
figuraTriangolo.t.p1 = ...
/* etc */

figuraTriangolo.cp(&figuraTriangolo.t);

/* Qui il punto. Posso usare figura Triangolo anche per un pentagono.
figuraTriangolo.cp = CalcolaPentagono; // ora posso solo usare un pentagono
figuraTriangolo.p.p1 = ...

figuraTriangolo.cp(&figuraTriangolo.p);


Come vedi, usare una union non di per se sbaglaito, ma pu creare un p di confusione.

chu
18-08-2010, 13:45
Perfetto ti ringrazio molto, ho messo i puntatori void come parametro alle funzioni per calcolare i vari perimetri e al puntatore a funzione in figura e ora funziona. Ora un ultima cosa: mi sto preparando per l'orale del laboratorio in c e nel programma riportato "uso di campi di tipo "puntatore a funzione" per simulare chiamate di metodo con le struct" e l'esercizio sopra faceva parte delle esercitazioni e si riferiva proprio a questo argomento. Correggimi se sbaglio: in java abbiamo la programmazione ad oggetti e quindi in una classe abbiamo variabili e metodi d'istanza, in C la programmazione ad oggetti non c' ma "emulabile" attraverso le struct e l'inserimento al loro interno di puntatori a funzione, giusto?
Grazie ancora!

MacApp
18-08-2010, 13:56
Originariamente inviato da chu
in C la programmazione ad oggetti non c' ma "emulabile" attraverso le struct e l'inserimento al loro interno di puntatori a funzione, giusto?

S

Loading