Tecniche di programmazione ad oggetti con il linguaggio C.
Nascondere i metodi
Dato che la funzione che implementa un metodo della nostra classe simulata è una funzione a tutti gli effetti, potrebbe essere possibile invocarla senza transitare dall'inizializzazione della classe simulata stessa. Vale a dire, il metodo è anche una funzione esterna all'oggetto stesso, invocabile contemporaneamente al metodo dell'oggetto. Il fatto che ciò sia possibile non equivale certo a doverlo per forza effettuare per "vedere cosa succede", ma se è possibile implementare meccanismi semplici di filtraggio non è certo una cattiva idea.
Quindi torniamo ad analizzare il nostro header yedstd.h, e precisamente l'ultima macro rimasta:
define PRIVATE_FUNCTION static |
Nel caso in cui i file yedprova.c e yedprova.h vengano compilati per realizzare un oggetto binario, anteporre nel prototipo della funzione la nostra macro PRIVATE_FUNCTION , che non è altro che la keyword static , permette al linker che prima o poi deve essere per forza invocato di nascondere l'intero simbolo alla globalità dell'applicazione. Il simbolo resta visibile, ma solo al modulo che lo referenzia, non verso l'esterno. Il risultato è un compilatore che non trova l'eventuale simbolo chiamato impropriamente, di fatto filtrando invocazioni "spurie" di metodi senza transitare dall'istanza della classe simulata.
Il nostro codice yedprova.c assume dunque la sua forma finale:
#include <stdio.h>
#include "yedstd.h"
#include "yedprova.h"
// COSTRUTTORE DINAMICO OGGETTO DI TIPO Cprova
Cprova *_Cprova(void)
{
Cprova *this;
if((this=(Cprova *)malloc(sizeof(Cprova)))!=NULL)
{
memset(this,0,sizeof(Cprova));
this->metodo=metodo;
this->PRIVATE(foo_priv)=2;
}
return this;
}
// DISTRUTTORE DINAMICO OGGETTO DI TIPO Cprova
Cprova *_DCprova(void *this)
{
free(this);
}
PRIVATE FUNCTION int metodo(void *pVWork)
{
Cprova *this=pvWork;
printf("Invocazione metodo: elemento interno [%d]\n",
this->PRIVATE(foo_priv));
return 0;
} |
mentre il file header yedprova.h diventa
#ifndef _Cprova
#define _Cprova
#include "yedstd.h"
typedef struct
{
char PRIVATE(foo_priv);
PUBLIC int (*metodo)(void *);
PUBLIC char elemento;
} Cprova;
/**** PROTOTIPO METODI ****/
PRIVATE_FUNCTION int metodo(void *);
#endif |
L'utilizzo della macro PRIVATE_FUNCTION per incapsulare realmente le funzionalità di un oggetto ed impedire invocazioni improprie dei suoi metodi si scontra però con la fattibilità del meccanismo di ereditarietà, permesso all'interno del progetto Yed. Nei paragrafi relativi viene introdotto il concetto di ereditarietà all'interno del progetto Yed e messa in evidenza la derivante collisione con l'isolamento dei metodi di un oggetto attraverso la keyword static.
|