Dipartimento di fisica “E


La Classe SistemaSolare: Attributi e Metodi



Scaricare 1.8 Mb.
Pagina8/24
12.12.2017
Dimensione del file1.8 Mb.
1   ...   4   5   6   7   8   9   10   11   ...   24

La Classe SistemaSolare: Attributi e Metodi


La discussione, affrontata in uno dei precedenti paragrafi, sulla struttura dell’intero programma di simulazione, ci permette di definire gli attributi ed i metodi, della classe SistemaSolare:



pianeti (CorpoCeleste **)

N (num. intero)



SistemaSolare(int n)

~SistemaSolare()

int aggiungiPianeta(CorpoCeleste * unPianeta)

void evolvi(float T, float dt)

int nPianeti()

La classe SistemaSolare contiene come attributi il numero N di pianeti che costituiscono il sistema solare e la lista di pianeti ( CorpoCeleste ** pianeti ). I metodi sono, oltre al costrutture e al distruttore, un metodo per aggiungere un pianeta al sistema solare ( int aggiungiPianeta(CorpoCeleste * unPianeta) ), un metodo per far evolvere il sistema per un tempo T con passo dt ( void evolvi(float T, float dt) ), ed un metodo di tipo Get per ottenere il numero di pianeti che fanno parte del sistema solare ( int nPianeti() ). L’argomento del costruttore ( int n ) e’ il numero massimo di pianeti che possono far parte del sistema solare. I dettagli della struttura della classe saranno chiari nel corso dell’implementazione: prima di affrontare l’implementazione della classe in C++ vogliamo pero’ discutere brevemente come e’ possibile gestire un insieme di dati in maniera semplice, in modo da chiarire il significato e le caratteristiche dell’attributo pianeti.



Esempio di una struttura dati: la lista dei pianeti


La classe SistemaSolare deve conoscere quali sono i pianeti che la costituiscono. Nel capitolo dedicato al disegno abbiamo identificato la relazione tra le due classi come una relazione di aggregazione: la classe SistemaSolare puo’ accedere ai pianeti di cui e’ composta attraverso i puntatori dei pianeti. Questa struttura ha il vantaggio di rendere independenti le caratteristiche e l’esistenza stessa dei pianeti dalla classe SistemaSolare: se lo desidero, posso accedere, dal programma main(), direttamente ai pianeti e cambiare alcune loro caratteristiche oppure utilizzarli nuovamente per una nuova simulazione, senza che la distruzione di un oggetto della classe Sistema Solare comporti la distruzione anche dei pianeti che lo compongono. Oltre a questi vantaggi di disegno, l’uso dei puntatori ha altri vantaggi di carattere generale: i puntatori permettono infatti di accedere ad oggetti anche complessi attraverso una variabile che richiede poco spazio in memoria, il suo puntatore appunto, senza la necessita’ di maneggiare o di copiare spesso oggetti molto grandi. Inoltre, come discuteremo nei prossimi due capitoli, l’uso dei puntatori permette di sfruttare sino in fondo le potenzialita’ dell’ereditarieta’ e del polimorfismo. Come discusso in dettaglio nel capitolo precedente, l’uso dei puntatori richiede pero’ attenzione nella gestione della memoria.

Supponiamo ora di voler memorizzare una serie di vettori che contengono i dati di una serie successiva di misure sperimentali. Chiamiamo vec1[0] … vec1[3]; vec2[0] … vec2[2]; vec3[0] ... vec3[4]; vec4[0] … vec4[1] ; le quattro serie successive di misure, ciascuna delle quali ha una dimensione variabile. Ogni vettore puo’ essere identificato con il suo puntatore: ad esempio il vettore vec1[0] … vec1[3] puo’ essere identificato dal suo puntatore, che, come sappiamo dalle relazioni tra puntatori e vettori, e’ semplicemente vec1. I quattro puntatori ( vec1 vec2 vec3 vec4 ) di ciascuna serie di dati possono essere a loro volta memorizzati in un altro vettore p[0] … p[3], conoscendo il quale possiamo accedere ai quattro vettori che contengono i dati. Per accedere al vettore p[0] … p[3] e’ sufficiente conoscere il puntatore ad esso, e quindi p. Oserviamo che i vettori vec1[0] … vec1[3]; vec2[0] … vec2[2]; vec3[0] ... vec3[4]; vec4[0] … vec4[1] sono, nel nostro esempio, di tipo int, per cui il vettore p[0] … p[3] e’ di tipo int *. Di conseguenza q, che e’ un puntatore al vettore p[0] … p[3] sara’ di tipo int **.

In figura 3 e’ riportata l’intera struttura appena descritta ed una parte di codice C++ che permette di rappresentare i dati in questa forma.


Figura 3: Schema di insieme di organizzazione di una struttura dati.


Nel caso della lista dei pianeti presente in Sistemasolare, gli oggetti ai quali vogliamo fare riferimento sono i Corpi Celesti: i puntatori ai Corpi Celesti possono essere memorizzati in un vettore di puntatori a Corpi celesti ( CorpoCeleste * ), al quale si potra’ accedere mediante il suo puntatore, che chiamiamo pianeti e che sara’ di tipo CorpoCeleste **. In figura 4 e’ riportato uno schema che evidenzia le relazioni tra i vari elementi della struttura.


Figura 4: Schema di insieme della gestione della lista dei pianeti in Sistema Solare. Alla lista si accede mediante il puntatore q (che in SistemaSolare si chiama pianeti) e che e’ di tipo Corpoceleste **

Osserviamo come questo modo di organizzare i dati sia piuttosto artigianale: nel seguito descriveremo l’uso di strutture piu’ professionali, quali i container STL. Lo studio di questo modo di organizzare i dati risulta comunque utile per capire meglio l’uso dei puntatori e per avere un esempio di come organizzare in maniera personale un insieme semplice di dati sperimentali.


Definizione della classe SistemaSolare: l'header file SistemaSolare.h


La definizione della classe SistemaSolare e' contenuta nel file SistemaSolare.h, che assume la forma seguente:
#include "CorpoCeleste.h"

#define G 6.673e-11


class SistemaSolare {

protected:

CorpoCeleste ** pianeti; // lista dei pianeti

int N; // numero dei pianeti


public:
SistemaSolare(int n);

~SistemaSolare();

int aggiungiPianeta(CorpoCeleste *unPianeta);

int nPianeti{return N;};

void evolvi(float T, float dt);

};

La struttura del file e’ immediata. Osserviamo che solo in metodo nPianeti() e’ implementato in SistemaSolare.h, mentre tutti gli altri metodi, incluso il distruttore, verranno implementati nel file SistemaSolare.cc. All’inizio del file e’ necessario includere CorpoCeleste.h, poiche’ e’ necessario che il compilatore sappia che esistono oggetti di nome CorpoCeleste e quale e’ la loro struttura. Tramite la direttiva di pre-compilazione #define si puo’ definire il valore della costante di Gravitazione universale G: tutte le volte che il compilatore incontrera’ il carattere G, maiuscolo ed isolato, lo sostituira’ con il valore numerico 6.673e-11. Come si può notare l’istruzione define non rappresenta una riga di programma: infatti essa non termina con il punto e virgola. Essa rappresenta, così come l’include, una direttiva al compilatore che interpreta la riga ed esegue delle operazioni durante la fase di compilazione (e non di esecuzione) del programma.






Condividi con i tuoi amici:
1   ...   4   5   6   7   8   9   10   11   ...   24


©astratto.info 2019
invia messaggio

    Pagina principale