Programmazione orientata agli oggetti in ANSI-C. La classe Point rivista e corretta -2

Un altro problema riguarda il fatto che Point_ctor() chiama il selettore della superclasse e di conseguenza non necessita di importare gli oggetti parametri come faceva Point_draw().

E' probabilmnete una buona idea se abbiamo un modo per dire ogni volta a ooc se vogliamo importare o meno e verificare o meno gli oggetti.

if there is a new metaclass
for all methods in %-
void draw (const void * _self) { // selector

% PointClass Circle: Point { // header
int rad; // object component
%}

Questa descrizione semplicissima contiene sufficienti informazioni che potremmo giàù generare i file di interfaccia. Ecco un pattern invece per dare un'idea di come ooc creerebbe Point.h.

#ifndef Point_h
#define Point_h
#include "Object.h"
extern const void * Point;
for all methods in %
void move (void * self, int dx, int dy);
if there is a new metaclass
extern const void * PointClass;
for all methods in %-
void draw (const void * self);
void initPoint (void);
#endif

Le parti indicate in grassetto si riferiscono a pattern comuni a tutti i file di interfaccia. Il font standard indica le informazioni che ooc deve leggere nella descrizione di classe e inserire all'interno dei file interfaccia. Le liste dei parametri sono da manipolare: _self o const _self sono convertite in adeguati puntatori, gli altri parametri possono essere copiati direttamente.

const struct PointClass * class = classOf(_self);
assert(class -> draw);
class -> draw(self);
}
// superclass selector
void super_draw (const void * class, const void * _self) {
const struct PointClass * superclass = super(class);
assert(_self && superclass -> draw);
superclass -> draw(self);
}

Se la descrizione di classe definisce una nuova metaclasse, possiamo generare tutti i selettori e i selettori della superclasse per tutti i nuovi metodi linkati dinamicamente. Se vogliamo farlo, in ogni selettore possiamo usare cicli di iterazione sui parametri e verificare che non ci siano puntatori null al posto degli oggetti.

if there is a new metaclass
// metaclass constructor
static void * PointClass_ctor (void * _self, va_list * app) {
{ struct PointClass * self =
super_ctor(PointClass, _self, app);
typedef void (* voidf) ();
voidf selector;
va_list ap = * app;
while ((selector = va_arg(ap, voidf)))
{ voidf method = va_arg(ap, voidf);
for all methods in %-
if (selector == (voidf) draw)
{ * (voidf *) & self -> draw = method;
continue;
}
}
return self;
}

Con un'iterazione sulle definizioni dei metodi nella descrizione di classe possiamo completamente generare i costruttori della metaclasse. In qualche modo, comunque, dovremmo dire ad ooc quale è l'header appropriato del metodo da usare per ctor() - un progetto diverso potrebbe decidere di utilizzare convenzioni diverse per i costruttori.

if there is a new metaclass
// metaclass constructor
static void * PointClass_ctor (void * _self, va_list * app) {
{ struct PointClass * self =
super_ctor(PointClass, _self, app);
typedef void (* voidf) ();
voidf selector;
va_list ap = * app;
while ((selector = va_arg(ap, voidf)))
{ voidf method = va_arg(ap, voidf);
for all methods in %-
if (selector == (voidf) draw)
{ * (voidf *) & self -> draw = method;
continue;
}
}
return self;
}

La funzione di inizializzazione dipende da un'iterazione su tutti i metodi linkati dinamicamente e sovrascritti nell'implementazione stessa.

Scarica subito una copia gratis

Scrivi un commento

Seguici anche sul tuo Social Network preferito!

Send this to a friend