Dipartimento di fisica “E


La direttiva di compilazione #ifndef



Scaricare 1.8 Mb.
Pagina14/24
12.12.2017
Dimensione del file1.8 Mb.
1   ...   10   11   12   13   14   15   16   17   ...   24

La direttiva di compilazione #ifndef


Utilizzando il meccanismo dell'Ereditarieta', accade frequentemente che un header file venga incluso piu' volte, poiche' si includono gli header file di piu' classi che ereditano da essa, ciascuno dei quali contiene l'header file della classe da cui tutte le altre ereditano. In questo caso il compilatore da' un messaggio di errore, poiche' trova una definizione multipla di una clsse. Per ovviare a questa difficolta' e' sufficiente utilizzare una direttiva di pre-compilazione, che puo' essere utilizzata in tutti gli header file, indipendentemente dal fatto che si preveda di utilizzare o no il meccanismo dell'ereditarieta'. Ad esempio, gli header file SistemaSolare.h e Sonda.h possono essere modificati nella forma:

#ifndef SISTEMASOLARE H

#define SISTEMASOLARE H
class SistemaSolare {

...........................................

};

#endif // SISTEMASOLARE H



#ifndef SONDA H

#define SONDA H

#include "CorpoCeleste.h"
class Sonda : public CorpoCeleste {

...........................................

};

#endif // SONDA H







Figura 7: Lo schema di memorizzazione dei pianeti in SistemaSolare permette di inserire indifferentemente, grazie al meccanismo dell'ereditarieta', puntatori ad oggetti di tipoCorpoCeleste e ad oggetti di tipoSonda.

Si confronti questa figura con la figura 4.


La variabile NOMECLASSE_H viene utilizzata per controllare se la classe e' gia' stata definita: se la variabile non e' stata definita, ( #ifndef NOMECLASSE_H ), viene definita ( #define NOMECLASSE_H ) e la compilazione del programma continua normalmente. Se invece la variabile e' gia' stata definita, cioe' se la classe e' gia' stata dichiarata poiche' l'header file e' gia' stato incluso in qualche altra parte del programma, la direttiva #ifndef NOMECLASSE_H ha come risultato "falso" e la com-pilazione continua dalla prima istruzione successiva alla direttiva di #endif, che nel nostro caso coincide con la fine del file di dichiarazione della classe. L'utilizzo di NOMECLASSE_H e' una convenzione non obbligatoria ma utile: scrivendo tutto in maiuscolo ed indicando tramite il trattino ( _ ) a quale tipo di file ci stiamo riferendo ( .h .cc .cpp o altri) ci puo' aiutare ad evitare errori o ad utilizzare variabili gia' utilizzate da altro o gia' definite in quanto nomi delle classi. L'indicazione della variabile dopo la direttiva #endif e' un commento, quindi non e' obbligatoria, ma aiuta a rendere piu' leggibile l'intero programma.

La sequenza di direttive #ifndef ...... #endif ha naturalmente anche altri usi, oltre a quello di impedire l'inclusione multipla di header file della stessa classe, ad esempio per cambiare od integrare parti di codice in funzione di parametri esterni: supponete ad esempio di voler trattare in maniera leggermente diversa un insieme di dati sperimentali ed un insieme di dati simulati, oppure dati sperimentali che derivano da prese dati differenti e che quindi sono leggermente diversi: l'uso di direttive di compilazione permette di introdurre in maniera molto efficiente variazioni nel codice, senza dover utilizzare due programmi diversi o senza affidarsi a tecniche strettamente orientate agli oggetti, qualora non se ne presenti la necessita’. Questo punto esula pero' dagli interessi del nostro corso, e comunque non presenta alcuna difficolta', essendo di immediata e semplice applicazione.


Polimorfismo




Il metodo giusto per ciascuna Classe


Puo' accadere che un concetto ben definito, applicato ad un oggetto di una classe, non possa essere espresso in maniera compiuta sino a che l'oggetto concreto della classe non sia precisato. Un esempio puo' chiarire questa affermazione. Consideriamo il concetto di area applicato ad una figura piana: il concetto e' ben definito, ma l'area non puo' essere calcolata sino a che non viene precisato di quale figura piana si tratta. In altri casi il concetto che vogliamo esprimere e' una sorta di "idea comune" che vale per oggetti di classi diverse, ma "un'idea comune" che puo' essere espressa in forme molteplici (poli-morfismo) a seconda degli oggetti ai quali si riferisce. Nella programmazione ad oggetti e' possibile fare in modo che venga scelto il "metodo giusto" da applicare in ciascun caso: nell'esempio precedente, si trattera' sempre del metodo Area(), ma sara' un metodo diverso a seconda che la figura geometrica alla quale si fa riferimento sia un traingolo, un quadrato, un esagono, ecc. La particolarita' di questa fondamentale proprieta' risiede nel fatto che la scelta del "metodo giusto" viene effettuata in maniera "automatica", senza che sia necessario alcun intervento prima di invocare il metodo: e' infatti possibile che l'utilizzatore nemmeno sappia a quale tipo di oggetto venga applicato il metodo in questione.

Nel seguito di questo capitolo preciseremo meglio il concetto di polimorfismo e successivamente indicheremo in quale modo tale proprieta' possa essere implementata e utilizzata nel linguaggio C++. In seguito applicheremo il Polimorfismo alla simulazione del Sistema Solare, inserendo le Sonde all'intermo della simulazione e concluderemo indicando alcune ulteriori caratterizzazioni che il Polimorfismo permette di introdurre nell'ambito del concetto di Ereditarieta'.




Polimorfismo a Run Time e Polimorfismo a Compilation Time


La scelta del "metodo giusto" da utilizzare puo' avvenire durante l'esecuzione di un programma oppure durante la fase di compilazione: nel primo caso si parla di Polimorfismo a Run Time, nel secondo di Polimorfismo a Compilation Time. In questo capitolo ci occupiamo solo del Polimorfismo a Run Time, mentre affronteremo il Polimorfismo a Compilation Time nel capitolo dedicato alla Programmazione generica. In genere pero', quando si parla di Polimorfismo ci si riferisce al Polimorfismo a Run Time, a meno che il contesto non fornisca ulteriori indicazioni.

Importante e' comunque avere ben precisa la distinzione, poiche' i meccanismi di funzionamento dei due tipi di Polimorfismo sono completamente diversi.






Condividi con i tuoi amici:
1   ...   10   11   12   13   14   15   16   17   ...   24


©astratto.info 2019
invia messaggio

    Pagina principale