"classi" in C

From Sistemi Operativi
Jump to navigation Jump to search

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 (void)
{
	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:

  1. Ereditarietà
  2. Polimorfismo

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.

Download File

Download: classi.tgz