TecnoMan
TecnoMan Blog
void * è un tipo molto lasco che abbiamo sfruttato per costruire i metodi polimorfici e, in particolare, il nostro meccanismo per la selezione dei metodi linkati dinamicamente
Ipotizziamo che libooc.a è una libreria con un modulo initializers.o che definisce l'array initializers[] come mostrato sopra contenente solo il puntatore null.
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.
Le descrizioni di classe sono oggetti la cui vita può durare a lungo. Sono costanti ed esistono praticamente tanto quanto dura l'esecuzione dell'applicazione. Se possibile, tali oggetti sono inizializzati al tempo di compilazione.
Tecnicamente, i selettori delle superclassi possono essere usati solamente da metodi interni. Decidiamo di non controllare i parametri dei selettori della superclasse. E' davvero una saggia decisione.
cast() è basata su isOf() che chiama classOf e possibilmente super(). Entrambi i metodi seguono la nostra codifica standard e importano i loro parametri con %casts, che a turno chiama cast() per verificare se gli argomenti siano Oggetto o Classi …
Quindi, lasciamo che sia il selettore a controllare gli oggetti che non si trovano nella classe corrente e lasciamo che i metodi linkati dinamicamente controllino a loro volta gli oggetti nella loro propria classe.
L'idea base è chiamare cast() tutte le volte che è necessario. Quando un metodo staticamente linkato dereferenzia gli oggetti nella sua stessa classe, dovrebbe fare proprio questo;
Con gli assiomi di cui sopra, i metodi isA() e isOf() sono abbastanza semplici da implementare:
Come esempio di quanto possiamo fare con isOf() e come cast() può rendere più sicuro il codice, consideriamo le modifiche seguenti in relazione al programma di test.
Ogni oggetto viene manipolato tramite void *. Se da un lato ciò semplifica la scrittura del codice, non evita disastri: manipolare un non oggetto o un oggetto sbagliato in un metodo o peggio, selezionare un metodo da una descrizione di …
E' un esercizio interessante cominare Queue con Point e Circle per lo skeleton di un programma di grafica con capacità di ridisegno.
Permetteteci di dare un'occhiata a poche classi implementate da zero utilizzando ooc così che possiate apprezzare gli sforzi che abbiamo fatto nei paragrafi precedenti. Inizieremo con una implementazione di List, un buffer ad anello double-ended che ha la funzione di …
Object rappresenta qualcosa che è sia la forza che la debolezza della nostra tecnica. Il codice può essere posizionato in una descrizione di classe o implementazione, può essere trasformato o tradotto in un report o può essere nascosto da qualche …
Nella sezione 7.1 abbiamo visto che per lavorare su Point abbiamo bisogno di raccogliere le informazioni dalle sue superclassi, fino ad arrivare alla classe radice della gerarchia.
Sappiamo cosa deve fare ooc. Come scriviamo però il preprocessore? Per ragioni di efficienza, dovremmo basarci su piattaforme come lex o yacc, ma una prima implementazione è molto meno costosa se ci basiamo su un linguaggio di programmazione come awk …
Quali istruzioni per il preprocessing dovrebbe fornire ooc? Osservando quanto indicato nella sezione 7.1 ci sono tre aspetti in cui ooc potrebbe aiutare: dato un nome di un metodo, conoscere l'header del metodo; dato un metodo, controllare e importare i …
Lasciateci trarre qualche conclusione dall'esperimento nel preprocessing di Point. Abbiamo iniziato con una descrizione line-oriented molto ma molto semplice che possiamo riassumerer così come segue:
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().
Vogliamo ingegnerizzare un preprocessore ooc che ci aiuti nel mantenere coerenti le nostre classi con la codifica standard che ci siamo imposti come convenzione. Il miglior modo per progettare un preprocessore è quello di partire prendendo un esempio reale di …