Difference between revisions of ""classi" in C"
(Come scrivere una "classe" in C?) |
|||
Line 21: | Line 21: | ||
ptr->foo = &foo1; | ptr->foo = &foo1; | ||
printf ("%d", ptr->foo(4)); | printf ("%d", ptr->foo(4)); | ||
+ | free(ptr); | ||
return 0; | return 0; | ||
} | } |
Revision as of 23:13, 2 November 2014
Paradigma OOP in C
Quando in classe abbiamo parlato di puntatori a funzione mi e` subito venuto in mente una cosa del genere:
#include <stdio.h>
int foo1 (int x);
typedef struct classe
{
int data;
int (*foo) (int x);
} classe;
int main (void)
{
classe *ptr;
ptr = (classe*) malloc (sizeof (classe));
ptr->foo = &foo1;
printf ("%d", ptr->foo(4));
free(ptr);
return 0;
}
int foo1 (int x)
{
return x;
}
ptr->foo() assomiglia molto ad un metodo!
Primi problemi
- se l'utente mi cambia l'indirizzo a cui punta foo?
- come rendo privati eventuali campi che voglio nascondere all'utente? Incapsulamento
- come derivo nuove classi a partire da quelle gia` definite? Ereditarietà
- come implemento il Polimorfismo?
La mia soluzione (incapsulamento)
- Scrivere una "classe" per modulo, nel relativo header dichiarare solo "i metodi che dovranno essere public":
#ifndef H__CLASS_H__H
#define H__CLASS_H__H
/* la "classe" classe contiene una parola che puo`:
* -essere cambiata
* -essere stampata
*/
struct classe;
typedef struct classe classe;
/* constructor */
classe* classeCreate(void);
/* destructor */
void classeDestroy(classe *classe_ptr);
/* public methods */
void cambiaParola (classe *classe_ptr, char *hello);
void stampa(classe *classe_ptr);
#endif
Da notare che non ho definito la struttura, in questo modo l'utente che andra` ad utilizzarla non potra` accedere ai campi, sara` costretto ad utilizzare "i metodi" dichiarati.
- Implementare la relativa "classe":
#include "class.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
struct classe
{
/* i campi sono privati!! */
char *hello;
};
/* constructor implementation */
classe* classeCreate(void)
{
classe *classe_ptr = NULL;
classe_ptr = (classe* ) malloc (sizeof (classe));
if(classe_ptr == NULL)
return NULL;
memset (classe_ptr, 0, sizeof (classe));
classe_ptr->hello = (char *) malloc (9*sizeof (char));
strcpy (classe_ptr->hello, "default");
return classe_ptr;
}
/* destructor implementation */
void classeDestroy (classe *classe_ptr)
{
if (classe_ptr == NULL)
{
fprintf( stderr, "Null pointer error, classe_ptr is NULL\n");
exit (-4);
}
/* sono sicuro che hello != null, poiche` l'utente
* non puo` gestirla al di fuori dei public methods
*/
free (classe_ptr->hello);
free (classe_ptr);
}
/* public methods implementation */
void cambiaParola (classe *classe_ptr, char *src)
{
/* dealloco *hello e creo spazio per *src */
free (classe_ptr->hello);
classe_ptr->hello = (char *) malloc
( (strlen(src) +1)*sizeof(char));
strcpy (classe_ptr->hello, src);
}
void stampa (classe *classe_ptr)
{
printf ("%s\n", classe_ptr->hello);
}
/* private methods */
static void foo (void)
{
/* something */
}
- Per finire importare la "classe" ed utilizzarla:
#include "class.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main (int argc, char *argv)
{
classe *saluto;
/* creo la "classe" saluto */
saluto = classeCreate ();
/* provo a stampare, N.B. non ho la minima
* idea di come sia fatta la struttura.
* NON posso fare:
* printf ("%s", stampa->hello);
*/
//printf ("%s", stampa->hello);
stampa (saluto);
/* cambio la parola, N.B. non ho la minima
* idea di come sia fatta la struttura.
* NON posso fare:
* strcpy (stampa->hello, "ciao");
*/
//strcpy (stampa->hello, "ciao");
cambiaParola (saluto, "ciao");
stampa (saluto);
classeDestroy (saluto);
return 0;
}
Conclusione
Non so se il modo in cui ho affrontato il problema sia corretto o errato, sono aperto a qualunque suggerimento (anche uno stravolgimento della mia idea e` ben accetto). Rimangono ancora "aperti" i problemi:
Sarei felice di ricevere suggerimenti in proposito!
PS. Non ho scritto questo Topic per utilizzare il paradigma OOP in C, ero solo curioso di vedere se fossi riuscito o meno ad implementare qualcosa di simile al concetto di classe.