Programmazione orientata agli oggetti in ANSI-C. Inizializzazione di Liste – munch -1

Le descrizioni di classe sono essenzialmente oggetti statici. Dovrebbero esistere finchè il programma principale è in esecuzione. Tale fine viene realizzando creando oggetti quali variabili globali o statiche e inizializzandole a tempo di compilazione.

Il nostro problema è che dobbiamo chiamare Class_ctor() e gli altri costruttori di metaclasse per nascondere i dettagli dell'ereditarietà quando si inizializza una descrizione di classe. Le funzioni, tuttavia, possono essere chiamate solo al tempo di esecuzione.

Il problema descritto è noto come la chiamata a costruttori statici – gli oggetti con un tempo di vita uguale a quello del programma principale devono essere creati non appena main() va in esecuzione. Non vi è differenza fra la generazione dinamica o statica degli oggetti. InitPoint() e funzioni simili semplificano le convenzioni sulle chiamate e permettono di effettuare chiamate in qualsiasi ordine, ma il lavoro in ogni caso viene comunque fatto da new() e dai costruttori.

Ad un primo sguardo, la soluzione dovrebbe essere triviale. Se ipotizziano che ogni descrizione di classe linkata in un programma è veramente usata dobbiamo chiamare ogni funzione di inizializzazione all'inizio di main(). Sfortunatamente, non si tratta di un problema di source text processing. Ooc non può aiutare in questo caso perchè non conosce come le classi sono messe insieme all'interno del programma. Verificare il codice sorgente non aiuta perchè il linker potrebbe effettuare il fetching delle classi dalle librerie.

I moderni linkers come GNU Id permettono al compilatore di comporre un array di indirizzi dove ogni modulo oggetto può contribuire con elementi non appena viene linkato all'interno di un programma. Nel nostro caso, possiamo collegare l'indirizzo di tutte le funzioni di inizializzazione in un array di questo tipo e modificare main() per chiamare ogni funzione necessaria una alla volta. Tuttativa, questa caratteristica non è disponibile agli utilizzatori dei compilatori.

Dovrebbe studiare una soluzione alternativa che ci permetta di bypassare l'ostacolo. Definiamo un array initializers[] e modifichiamo il codice in main() come segue:

void (* initializers [])(void) = {
0 };
int main ()
{ extern void (* initializers [])(void);
void (** init)(void) = initializers;
while (* init)
(** init ++)();
...

Tutto ciò che rimane da fare è specificare ogni funzione di inizializzazione del nostro programma come un elemento di Inizializers[]. Se ci fosse un'utility come nm che può stampare la tabella dei simboli di un programma potremmo usare il seguente approccio per generare un array automaticamente:

$ cc —o task object... libooc.a
$ nm —p task | munch > initializers.c
$ cc —o task object... initializers.c libooc.a
Scarica subito una copia gratis

Scrivi un commento

Seguici anche sul tuo Social Network preferito!

Send this to a friend