Dipartimento di fisica “E



Scaricare 84.5 Kb.
12.11.2018
Dimensione del file84.5 Kb.



Appendice



Esercitazioni di Laboratorio

Esercitazione di Laboratorio n. 1




  1. L’Account sul Computer in ambiente Linux

Username: didnm ( gruppo del martedi' )

oppure didnv ( gruppo del venerdi' )

[ dove n e’ il numero del Gruppo (2 cifre, da 01 a 16) ]


Nella propria home directory creare una directory LabCalc_II_2002_03

Spostarsi nella directory LabCalc_II_2002_03 e creare:

i) una sottodirectory source che conterra’ tutte le versioni finali di ciascuna
sezione dell’intero programma

ii) una sottodirectory esercit_m per ciascuna delle esercitazioni svolte.


[ m e’ il numero dell’esercitazione ]

iii) un file Nomi_n.txt che contenga i nomi degli appartenenti al gruppo n


1) Esercizio di "familiarizzazione" con il C++


i) Definire la classe CorpoCeleste (CorpoCeleste.h)

ii) Implementare la classe CorpoCeleste (CorpoCeleste.cc)

iii) Costruire un programma main (Esercit_1.cpp) che

- istanzi un certo numero di oggetti CorpoCeleste;

- ne stampi su video l'elenco con le caratteristiche;

- riempia un vettore di oggetti CorpoCeleste;

- riempia un vettore di puntatori a oggetti di tipo CorpoCeleste.

- ne stampi su video l'elenco con le caratteristiche



Osservazioni
1) Per rendere piu' esplicito il ruolo del Distruttore, e' utile implementare il Distruttore in forma intelligente, con un messaggio che avverta l'utente dell'avvenuta distruzione.

In CorpoCeleste.h aggiungere le istruzioni che definiscono e implementano il distruttore:


~CorpoCeleste() {

cout << endl << " sono nel distruttore di Corpo eleste!!"



<< endl;

};
(se volete, potete anche stampare il nome del pianeta che viene distrutto)

(Nel caso precedente il distruttore era fornito dal compilatore, in quanto non esplicitamente
definito)

2) Per permettere di istanziare un Corpoceleste o un vettore di oggetti di tipo CorpoCeleste, e' necessario introdurre il costruttore senza parametri, che viene spesso utilizzato. In CorpoCeleste.h e’ implementato tale costruttore: verificare che se non e’ presente il Costruttore senza parametri, non e’ possibile istanziare un vettore di oggetti di tipo CorpoCeleste


Se volete, potete implementare un Costruttore intelligente, con un messaggio che vi aiuti a capire che cosa sta succedendo e come viene gestita la memoria.

Esempi di Programmi main che eseguono quanto richiesto nell’esercitazione n. 1



Versione n. 1 (Es_1a.cpp)

La versione piu' semplice, che istanzia tre oggetti e ne stampa alcune caratteristiche

==============
#include

#include

#include

#include "CorpoCeleste.h"

int main () {
// istanzio una serie di oggetti di tipo CorpoCeleste
CorpoCeleste sole("Sole", 2.e30,0.,0.,0.,0.);

CorpoCeleste pietra("dolomite",1.,0.,0.,1.,1.);

CorpoCeleste sasso("quarzo",2.,1.,0.,0.,1.);
// Scrivo alcune caratteristiche degli oggetti che ho istanziato;

// Ad esempio la massa e la posizione

cout << endl << "Pianeta n. Massa Posizione iniziale " << endl

<< " x y "

<< endl << endl;
cout << " " << "1" << " " << sole.M()

<< " " << sole.X() << " " << sole.Y() << endl;
cout << " " << "2" << " " << pietra.M()

<< " " << pietra.X() << " " << pietra.Y() << endl;
cout << " " << "3" << " " << sasso.M()

<< " " << sasso.X() << " " << sasso.Y() << endl;

cout << endl;


// Il programma e' finito.

// Notate (tramite il distruttore intelligente) che il compilatore

// provvede a distruggere gli oggetti di tipo CorpoCeleste

// (sole, pietra, sasso).

//
return 0;
}


Versione n. 2 (Es_1b.cpp)

Modifica della versione precedente, con allocazione dinamica e quindi con l'uso di new e delete.

==============

#include

#include

#include

#include "CorpoCeleste.h"
int main () {
// istanzio una serie di oggetti di tipo CorpoCeleste

// Uso l'allocazione dinamica della memoria, tramite new

CorpoCeleste * Psole = new CorpoCeleste("Sole", 2.e30,0.,0.,0.,0.);

CorpoCeleste * Ppietra = new CorpoCeleste("dolomite",1.,0.,0.,1.,1.);

CorpoCeleste * Psasso = new CorpoCeleste("quarzo",2.,1.,0.,0.,1.);
// Scrivo alcune caratteristiche degli oggetti che ho istanziato;

// Ad esempio la massa e la posizione

cout << endl << "Pianeta n. Massa Posizione iniziale " << endl

<< " x y "

<< endl << endl;

cout << " " << "1" << " " << Psole->M()



<< " " << Psole->X() << " " << Psole->Y() << endl;
cout << " " << "2" << " " << Ppietra->M()

<< " " << Ppietra->X() << " " << Ppietra->Y() << endl;
cout << " " << "3" << " " << Psasso->M()

<< " " << Psasso->X() << " " << Psasso->Y() << endl;
cout << endl;
// Ora devo cancellare gli oggetti allocati dinamicamente tramite new
cout << endl << "Prima delle chiamate a delete " << endl;

delete Psole; delete Ppietra; delete Psasso;


cout << endl << "Dopo le chiamate a delete " << endl;

// Il programma e' finito

// Notate (tramite il distruttore intelligente) che il compilatore

// ha provveduto a distruggere gli oggetti di tipo CorpoCeleste

// ai quali puntavano Psole, Ppietra, Psasso.

return 0;


}

Versione n. 3 (Es_1c.cpp)

Programma con l'uso di vettore di oggetti e di un vettore di puntatori ad oggetti (molto piu' elegante)

==============

#include

#include

#include

#include "CorpoCeleste.h"
int main () {

// uso un vettore di oggetti di tipo Corpoceleste


const int np = 6;

CorpoCeleste Pianeti[np];

// Con un loop scrivo gli elementi del vettore

for (int i=0; i

CorpoCeleste Ausiliario("",i,i,i,i,i);

Pianeti[i] = Ausiliario;

}

// Con un loop posso estrarre le informazioni. Ad esempio la massa


cout << endl << "Pianeta n. Massa Posizione iniziale " << endl

<< " x y "

<< endl << endl;
for ( int i=0; i

cout << " " << i+1 << " " << Pianeti[i].M()



<< " " << Pianeti[i].X() << " "

<< Pianeti[i].Y() << endl;

}

cout << endl;


//


// Ora uso un vettore di puntatori a oggetti di tipo CorpoCeleste

const int npp = 8;

CorpoCeleste* MieiPianeti[npp];

// Con un loop scrivo gli elementi del vettore


for ( int i=0; iMieiPianeti[i] = new CorpoCeleste(" ",i,i,i,i,i);

}

cout << endl



<< endl << " ************ Con i puntatori **************** "

<< endl << endl;

// Con un loop posso estrarre le informazioni. Ad esempio la massa


cout << endl << "Pianeta n. Massa Posizione iniziale " << endl

<< " x y "

<< endl << endl;
for ( int i=0; icout << " " << i+1 << " " << MieiPianeti[i]->M()



<< " " << MieiPianeti[i]->X() << " "

<< MieiPianeti[i]->Y() << endl;

}

cout << endl;


// devo ricordarmi di cancellare gli oggetti allocati dinamicamente
for ( int i=0; i

cout << i+1;

delete MieiPianeti[i];

}
return 0;


}

Versione n. 4 (Es_1d.cpp)

Programma con l'uso di una allocazione dinamica del vettore di oggetti e del vettore di puntatori ad oggetti, con l'uso di new e di delete.

==============
#include

#include

#include

#include "CorpoCeleste.h"


int main () {

// uso un vettore di oggetti di tipo Corpoceleste

// Il vettore di oggetti e' allocato dinamicamente

// tramite new, che fornisce il puntatore all'array


const int np = 6;

CorpoCeleste * Pianeti= new CorpoCeleste[np];

// Con un loop scrivo gli elementi del vettore

for (int i=0; i

CorpoCeleste Ausiliario("",i,i,i,i,i);

Pianeti[i] = Ausiliario;

}
// Con un loop posso estrarre le informazioni. Ad esempio la massa

cout << endl << "Pianeta n. Massa Posizione iniziale " << endl



<< " x y "

<< endl << endl;
for ( int i=0; icout << " " << (i+1) << " " << Pianeti[i].M()



<< " " << Pianeti[i].X() << " "

<< Pianeti[i].Y() << endl;

}


// Ora devo cancellare il vettore allocato dinamicamente
cout << endl << endl << " Prima di chiamare delete [] Pianeti " << endl;

delete [] Pianeti;

cout << endl << " Dopo aver chiamato delete [] Pianeti " << endl;

// Ora uso un vettore di puntatori a oggetti di tipo CorpoCeleste

// Il vettore di puntatori e' a sua volta allocato dinamicamente,

// tramite new, che fornisce il puntatore all'array di puntatori.

// Per questo motivo la prima chiamata di new istanzia un oggetto di

// tipo CorpoCeleste ** , cioe' un puntatore ad un puntatore.


const int npp = 8;

CorpoCeleste** MieiPianeti = new CorpoCeleste*[npp];

// Con un loop scrivo gli elementi del vettore
for (int i=0; i

MieiPianeti[i] = new CorpoCeleste(" ",i,i,i,i,i);

}

cout << endl



<< endl << " ************ Con i puntatori **************** "

<< endl << endl;
// Con un loop posso estrarre le informazioni. Ad esempio la massa
cout << endl << "Pianeta n. Massa Posizione iniziale " << endl

<< " x y "

<< endl << endl;
for (int i=0; i

cout << " " << i+1 << " " << MieiPianeti[i]->M()



<< " " << MieiPianeti[i]->X() << " "

<< MieiPianeti[i]->Y() << endl;

}

cout << endl;


// devo ricordarmi di cancellare gli oggetti allocati dinamicamente

// e poiche' ho usato new a due livelli, chiamero' delete 2 volte


// 1 - per I puntatori agli oggetti di tipo CorpoCeleste

// (cioe' gli oggetti contenuti nell'array di puntatori

cout << endl << " Prima del loop con delete MieiPianeti[i] " << endl;

for (int i=0; i

cout << i+1;

delete MieiPianeti[i];

}

cout << endl << " Dopo il loop con delete MieiPianeti[i] " << endl;



// 2 - per l'array di puntatori

delete [] MieiPianeti;


return 0;
}


Esercitazione di Laboratorio n. 2


Esercizio di "Incapsulamento" con il C++


i) Modificare la classe CorpoCeleste ed usare una rappresentazione in coordinate polari (si puo' tralasciare la modifica del metodo CorpoCeleste::CalcolaPosizione, che però dovrà essere commentato);

ii) Verificare che il programma main dell’Esercitazione n. 1 funziona allo stesso modo, senza la necessita' di alcuna modifica;




N.B.
Le relazioni di trasformazione tra i diversi sistemi di coordinate sono:
1) Da coordinate polari a coordinate cartesiane



2) Da coordinate cartesiane a coordinate polari




Esercitazione di Laboratorio n. 3

Esercizio di "Debug" del metodo CorpoCeleste::CalcolaPosizione


i) Nella rappresentazione originaria (coordinate cartesiane) applicate una forza costante e studiate il moto del pianeta;

ii) Come caso particolare studiate il moto di un proiettile e la caduta di un grave in un fluido (ad esempio il moto di una pietra lanciata in acqua)

iii) Esprimete il risultato sotto forma di tabella calcolata a istanti successivi

Lavoro di Gruppo n. 1


Analizzate attentamente quanto richiesto dal testo dell’Esercitazione n.3.


1) Perche’ la classe CorpoCeleste può essere utilizzata per risolvere il problema indicato? Quali metodi della classe CorpoCeleste dovranno essere invocati per ottenere il risultato richiesto?


  1. Quale e’ la strategia che volete utilizzare per ottenere il risultato finale? Scrivete un interaction diagram dell’intero programma (main e chiamate ai metodi di CorpoCeleste)




  1. Suddividetevi i compiti nel gruppo. Uno di voi sara’ il programma main, alcuni altri possibili istanze di oggetti di tipo CorpoCeleste, altri ancora dovranno solo controllare che tutto si svolga senza errori. Tutti devono avere a disposizione l’elenco dei metodi di CorpoCeleste e conoscerne il funzionamento.




  1. Il main effettui tutte le chiamate necessarie

  2. I singoli oggetti eseguano quanto richiesto (se possibile!) ed invochino eventuali altri metodi




  1. Discutete quanto emerso nel corso del punto 3) e confrontatelo con la struttura dell’intero programma di SistemaSolare.


N.B. Il punto 3) (e l’eventuale discussione) potra’ essere ripetuta più volte cambiando il ruolo degli “attori” ed in riferimento alle richieste i) e ii) dell’Esercitazione di Laboratorio n. 3

Esercitazione di Laboratorio n. 4


Definizione ed Implementazione della Classe Sistema Solare
Definite la classe Sistema Solare ( file SistemaSolare.h )
ed implementatela ( file SistemaSolare.cc ) secondo lo schema
discusso a lezione e descritto nelle dispense
Programma di Simulazione
Scrivere un programma main ( Simula.cpp ) che istanzi un certo numero
di CorpiCelesti ed un oggetto di tipo Sistema Solare e determini la
traiettoria dei Corpi Celesti.

Esercitazione di Laboratorio n. 5


Definire ed Implementare la classe Sonda (Sonda.h e Sonda.cc) secondo lo schema discusso a lezione e descritto nelle dispense.

In particolare discutere quanto segue:


Perche’ e’ possibile aggiungere una sonda nel sistema solare senza cambiare nulla nella definizione e nella implementazione della classe Sistema Solare?
Quali variazioni e’ necessario apportare alla Classe CorpoCeleste?

(in particolare ai metodi calcola Posizione e al Distruttore)

Perche’ nel metodo CalcolaPosizione di Sonda viene invocato esplicitamente il metodo calcolaPosizione di Corpo Celeste? E con quale sintassi?

Esercitazione di Laboratorio n. 6


Ereditarieta’, Polimorfismo e Metodi Virtuali

Definire ed Implementate una serie di classi legate tra loro da una relazione di Ereditarieta’: scegliete a vostro piacimento classi molto semplici, con pochi membri ed alcuni metodi di immediata comprensione. Ad esempio potete scegliere la classe Shape delle figure geometriche piane e far ereditare da essa la classe Cerchio, la classe Quadrato, Rettangolo ecc., e come metodi Area(), Print() oppure Tipo(), ecc. Altre scelte analoghe sono naturalmente possibili.


  1. Creazione di oggetti, vettori di oggetti e vettori di puntatori ad oggetti

Create una serie di oggetti ed applicate ad essi i vari metodi. Successivamente create un vettore di oggetti e ripetete le stesse operazioni. Verificate che solo utilizzando un vettore di puntatori potete mettere nello stesso vettore oggetti che ereditano dalla stessa classe o oggetti di classi legati tra loro da una relazione di ereditarieta’.


  1. Funzionamento dei costruttori e distruttori

Verificare, attraverso i costruttori ed i distruttori intelligenti, come funziona il meccanismo di creazione e di distruzione per classi legate tra loro da una relazione di ereditarieta’, sia nel caso di oggetti ai quali si accede direttamente, sia nel caso di oggetti ai quali si accede con puntatori della classe stessa o con puntatori alla classe da cui l’oggetto eredita.


  1. Uso di metodi virtuali

Utilizzando l’accesso agli oggetti attraverso i puntatori o mediante gli oggetti stessi, verificate il funzionamento del polimorfismo. Verificate quali risultati si ottengono definendo o non definendo alcuni metodi virtual. Verificate che solo definendo opportunamente alcuni metodi come virtual e’ possibile accedere correttamente ad essi attraverso un vettore di puntatori.


  1. Distruttori virtuali

Verificate il meccanismo di funzionamento dei distruttori, definendo o non definendo il distruttore come virtual. Accedete agli oggetti attraverso vettori di puntatori o attraverso gli oggetti stessi, e confrontate i risultati con quelli ottenuti ai punti 1 e 3



  1. Uso di classi astratte

Rendete la classe “piu’ in alto” nella catena ereditarieta’ una classe astratta, definendo almeno un metodo come pure virtual. Verificate che in questo caso

i) Tutte le classi che erditano devono fornire l’implementazione


del metodo pure virtual

ii) Non e’ possibile istanziare un oggetto della classe astratta



Esercitazione di Laboratorio n. 7


Overloading degli Operatori


Implementate la classe dei numeri complessi (che potreste ad esempio chiamare Compl), includendo anche l’algebra di composizione interna e le operazioni tra numeri complessi e numeri reali . In particolare dovrete implementare:


  • Costruttori (vuoto e conparametri) e distruttore

  • Metodi di tipo Set e metodi di tipo Get

  • Metodi per il calcolo del modulo e della fase

  • Gli operatori di somma, sottrazione, moltiplicazione e divisione tra numeri complessi

  • Gli operatori di somma, sottrazione, moltiplicazione e divisione o tra numeri complessi e numeri reali o interi

  • L’overloading dell’operatore cout in modo da scrivere un numero complesso nella forma a + bi dove a e b sono rispettivamente la parte reale e la parte immaginaria

Esercitazione di Laboratorio n. 8


Classi Template


1. Costruite una classe, che potrete ad esempio chiamare Matr, delle matrici a due indici, con un numero di righe e di colonne a vostra scelta (ad esempio 4x4). Il singolo elemento di matrice degli oggetti della classe Matr sia ad esempio un intero. In particolare dovrete implementare:

  1. Costruttori e distruttore ;

  2. Metodo di tipo Get che restituisce il puntatore agli elementid ella matrice;

  3. Un operatore membro, ad esempio l’operatore somma o l’operatore +=

Costruite un breve programma main() che istanzi oggetti della classe Matr e verifichi il corretto funzionamento dei metodi e degli operatori implementati
2. Modificate la classe Matr precedentemente definita e, dopo averla rinominata MatrT, fate in modo che il tipo di elemento di matrice sia un oggetto della classe template T. Modificate successivamente il programma main() in modo da istanziare vari oggetti della classe template MatrT in cui gli elementi di matrice siano int, oppure double, oppure Compl. Si verifichi il funzionamento corretto di tutti i metodi e dell’operatore implementato in MatrT.
3. Costruite due o tre classi, MatrInt MatrDbl MatrCompl , che ereditano dalla classe MatrT, avendo assegnato gli oggetti della classe template come oggetti di tipo int, double o Compl. Si modifichi ulteriormente il programma main() in modo da verificare il corretto funzionamento dei metodi e degli operatori delle nuove classi

Esercitazione di Laboratorio n. 9


Utilizzo di un Container


Costruite un programma main() che utilizzi il container vector della libreria standard STL per memorizzare oggetti di tipo CorpoCeleste tramite il loro puntatore ( CorpoCeleste * ). Inserire nel container puntatori ad oggetti di tipo CorpoCeleste e puntatori ad oggetti di tipo Sonda. Successivamente accedete agli elementi del container per visualizzare su video alcune caratteristiche degli oggetti (ad esempio la massa, la posizione, la velocita’).
Dopo aver verificato il corretto funzionamento del programma precedente, modificare la classe SistemaSolare in modo da memorizzare i pianeti che compongono un sistema solare tramite un container di tipo vector. In particolare tenere presente che:

i) L’attributo N della classe SistemaSolare puo’ essere eliminato, utilizzando il metodo size() del container di tipo vector;

ii) I costruttori SistemaSolare() e SistemaSolare(int n) devono essere opportunamente modificati. Quest’ultimo costruttore, di per se’ ora inutile, venga mantenuto per compatibilita’ con la versione precedente;

iii) I metodi aggiungiPianeta ed evolvi devono essere opportunamente modificati.

N.B. Per semplificare la notazione, in particolare nel caso degli iteratori, si puo’ utilizzare l’istruzione typedef che permette di associare ad un qualsiasi comando o stringa un alias. La sintassi e’:
typedef nomecomando alias ;

Ad esempio:



typedef vector::const_iterator CCIter ;
In questo modo sara’ possibile utilizzare l’ “abbreviazione” CCIter per indicare l’iteratore su un vettore di puntatori ad oggetti di tipo CorpoCeleste.




Condividi con i tuoi amici:


©astratto.info 2019
invia messaggio

    Pagina principale