Home
Accesso / Registrazione
 di 

Programmazione orientata agli oggetti in ANSI-C. Implementazione - seconda parte

Programmazione orientata agli oggetti in ANSI-C. Implementazione

respondsTo() deve cercare la descrizione di classe per un tag e restituire il corrispondente selettore. Di conseguenza, la descrizione di classe contiene solo puntatori ai metodi. Chiaramente l'entry del metodo in una descrizione di classe deve essere estesa:

typedef void (* Method) (); // for respondsTo()
%prot
struct Method {
const char * tag; // for respondsTo()
Method selector; // returned by respondsTo()
Method method; // accessed by the selector
};
% Class Object {
...
Method respondsTo (const _self, const char * tag);

Method è un tipo semplice di funzione definito nel file di interfaccia per Object. Ogni metodo è memorizzato in una descrizione di classe come componente del tipo struct Method che contiene i puntatori al tag, al selettore e al metodo corrente. RespondsTo() restituisce un Method.

Dato questa visione generale, sono però necessari alcune variazioni. In Object.dc abbiamo bisogno di cambiare l'inizializzazione statica delle descrizioni delle classi Object e Class per usare struct Method

static const struct Class _Object = {
{ MAGIC, & _Class },
"Object", & _Object, sizeof(struct Object),
{ "", (Method) 0, (Method) Object_ctor },
{ "", (Method) 0, (Method) Object_dtor },
{ "differ", (Method) differ,(Method) Object_differ },
...
};

Il report -r in r.rep usa il report link in va.rep per generare un entry nella descriozne di classe per il file di rappresentazione. La nuova versione del report link è molto molto semplice:

% link // component of metaclass structure
struct Method `method ;

Infine, il report init in c.rep e c-R.rep usa il metca-ctor-loop in etc.rep per generare il ciclo che dinamicamente riempie la descrizione di classe. Qui dobbiamo anche lavorare con i nuovi tipi:

% meta—ctor—loop // selector/tag/method tuples for `class
`t while ((selector = va_arg(ap, Method))) `n
`t { `t const char * tag = va_arg(ap, ` \
const char *); `n
`t `t Method method = va_arg(ap, Method); `n `n
`{%— `%link—it `}
`t } `n

% link—it // check and insert one selector/method pair
`t `t if (selector == (Method) `method ) `n
`t `t { `t if (tag) `n
`t `t `t `t self —> `method .tag = tag, `n
`t `t `t `t self —> `method .selector = selector; `n
`t `t `t self —> `method .method = method; `n
`t `t `t continue; `n
`t `t } `n

Piuttosto che le coppie selettore – metodo specifichiamo ora le tuple composte da selettore – tag – metodo come argomenti per il costruttore della metaclasse. Questo deve essere costruito nel report init in c.rep. Qui invece troviamo la funzione di inizializzazione che Wc genera tramite ooc:

static const void * _Wc;
const void * Wc (void) {
return _Wc ? _Wc :
(_Wc = new(WcClass(),
"Wc", Object(), sizeof(struct Wc),
wc, "line", Wc_wc,
printFile, "wrap", Wc_printFile,
printTotal, "quit", Wc_printTotal,
(void *) 0));
}

Date le tuple selettore tag metodo nella descrizione di classe, respondsTo() è facile da scrivere. Grazie alla gerarchia delle classi, possiamo calcolare quanti metodo una descrizione di classe contiene e possiamo implementare respondsTo interamente nella classe Object, anche se per sua natura si occupa di classi arbitrarie:

% respondsTo {
if (tag && * tag) {
const struct Class * class = classOf(_self);
const struct Method * p = & class —> ctor; // first
int nmeth =
(sizeOf(class) — offsetof(struct Class, ctor))
/ sizeof(struct Method); // # of Methods
do
if (p —> tag && strcmp(p —> tag, tag) == 0)
return p —> method ? p —> selector : 0;
while (++ p, —— nmeth);
}
return 0;
}

Il problema principale di questo approccio è che respondsTo() contiene esplicitamente il primo nome di metodo mai utilizzato e cioè ctor, che gli serve per calcolare il numero di metodi a partire dalla dimensione della descrizione di classe. Mentre ooc potrebbe ottenere questo nome dalla descrizione di classe di Object, potrebbe essere abbastanza complesso costruire un report per ooc in modo da generare respondsTo() con un approccio più generalistico.

 

 

Scrivi un commento all'articolo esprimendo la tua opinione sul tema, chiedendo eventuali spiegazioni e/o approfondimenti e contribuendo allo sviluppo dell'argomento proposto. Verranno accettati solo commenti a tema con l'argomento dell'articolo stesso. Commenti NON a tema dovranno essere necessariamente inseriti nel Forum creando un "nuovo argomento di discussione". Per commentare devi accedere al Blog
ritratto di @Facebook

ma uno non fa prima a

ma uno non fa prima a programmare in c++?

Gaetano Lombardo @Facebook

 

 

Login   
 Twitter Facebook LinkedIn Youtube Google RSS

Chi è online

Ci sono attualmente 27 utenti e 71 visitatori collegati.

Ultimi Commenti