UNIVERSITA’ DEGLI STUDI ROMA TRE
DIPARTIMENTO DI FISICA “E. AMALDI”
laboratorio di calcolo II
AA 2003/04
ottava settimana
a cura di
Domizia Orestano
Dipartimento di Fisica
Stanza 159 - tel. (06 5517) 7281
www.fis.uniroma3.it/~orestano
[email protected]
1
premessa
Relazioni tra Concetti ed Ereditarietà
«A concept does not exist in isolation. It coexists with related concepts
and derives much of its power from relationships with related
concepts…» (B. Stroustrup)
Relazioni tra concetti
Ereditarieta’
Indipendenza tra Concetti e Programmazione Generica
«Independent concepts should be independently represented and should
be combined only when needed. Where this principle is violated, you
either bundle unrelated concepts together or create unnecessary
dependencies. Either way, you get a less flexible set of components out of
which to compose systems…» (B. Stroustrup)
Concetti Indipendenti
Templates
2
L’implementazione di un metodo assume molte forme ( polimorfismo ) ed e’ possibile scegliere “automaticamente” la
“forma” giusta
Polimorfismo a Run Time
La forma “giusta” viene scelta durante
l’esecuzione del programma
Polimorfismo a Compilation Time
La forma “giusta” viene scelta durante
la compilazione del programma
Programmazione Generica
3
Esempio 1
Voglio contare le gocce di pioggia che cadono sulle mattonelle di
un pavimento
class Myfloor {
protected :
int element[4][4] ;
public:
// costruttori
// distruttore
// metodi di tipo set
// metodi di tipo get
// altri metodi (incremento)
// operatori
…………………………………..
} ;
4
Esempio 2
Voglio studiare la distribuzione di massa in una lastra non
omogenea
class Myplate {
protected :
double element[4][4] ;
public:
// costruttori
// distruttore
// metodi di tipo set
// metodi di tipo get
// altri metodi (incremento)
// operatori
…………………………………..
} ;
5
Esempio 3
Voglio studiare il capo elettrico su un reticolo
class Myfield {
protected :
ThreeVector element[4][4] ;
public:
// costruttori
// distruttore
// metodi di tipo set
// metodi di tipo get
// altri metodi (incremento)
// operatori
…………………………………..
} ;
6
Il problema
Stiamo scrivendo molte linee di codice praticamente identiche, ma
non possiamo ri-utilizzare il codice attraverso il meccanismo
dell’Ereditarietà, infatti da un lato non ci sono relazioni sfruttabili
tra le situazioni elencate e dall’altro attributi e metodi delle classi
che abbiamo visto sono di tipo diverso.
Ma la possibilità di ri-utilizzare del codice non era uno dei
cardini della programmazione OO?
7
Lezione 1: Requisiti per il software
moderno
1.
Robustezza
protezioni nell’accesso ai dati
2.
3.
4.
Possibilità di ri-utilizzo del codice
1.
economia di risorse umane ed economiche
2.
maggiore affidabilità
Portabilità
1.
verso sistemi operativi diversi
2.
verso diverse versioni di uno stesso sistema
Flessibilità e Organizzazione del Codice
semplicità di gestione e sviluppo successivo del codice
8
Esempio 4
Vogliamo calcolare il minimo tra due oggetti (per i quali sia definito un
ordinamento).
Definiamo una funzione minimo per ogni tipo di oggetto trattato:
double & minimo(const double & a1, const double & a2) {
if(a1<=a2) { return a1; } else { return a2;}
}
int & minimo(const int & a1, const int & a2) {
if(a1<=a2) { return a1; } else { return a2;}
}
TwoVect & minimo(const TwoVect & a1, const TwoVect & a2) {
if(a1<=a2) { return a1; } else { return a2} ;
}
9
La soluzione: le classi Template
Introduco un parametro T che rappresenta il tipo (la classe) cui
appartengono gli oggetti da trattare e implemento il codice in
funzione della generica classe T.
Specificando T (int, double, complex, TwoVector…) in fase di
compilazione ottengo il codice oggetto che tratta interi, reali in
doppia precisione, complessi, vettori a due componenti…
10
La sintassi delle classi Template
Dichiarazione (.h):
template <class T> class Myclass {
…………………………………
// T si puo’ usare come
// una classe qualsiasi
………………………………….
};
Implementazione (.icc):
template <class T> tipo Myclass<T>::nomemetodo(…) { …………… }
Implementazione (.cc):
export template <class T> tipo Myclass<T>::nomemetodo(…) { …………… }
11
Esempi 1,2 e 3
template <class T> class Mynet {
protected :
T element[4][4] ;
public:
// costruttori
// distruttore
Myfloor
Mynet<int>
Myplate
Mynet<double>
Myfield
Mynet<ThreeVector>
// metodi di tipo set
// metodi di tipo get
// altri metodi (incremento)
// operatori
…………………………………..
} ;
12
Uso di una classe Template
#include “Mynet.h”
int main()
{
………………
Mynet<int>
mi;
Mynet<double> mdb;
Mynet<TwoVector> mtv;
………………
return 0;
}
13
Template e ereditarietà
posso poi usare anche l’Ereditarietà, implementando solo costruttori e distruttori
class Myfloor : public Mynet<int> {
public:
// costruttori
#include “Mynet.h”
~Myfloor() {}; // distruttore
int main()
} ;
{
………………
class Myplate : public Mynet<double> {
Myfloor mi;
public:
// costruttori
Myplate mdb;
~Myplate() {}; // distruttore
Myfield mtv;
} ;
#include <TwoVector.h>
class Myfield : public Mynet<TwoVector> {
public:
………………
return 0;
}
// costruttori
~Myplate() {}; // distruttore
} ;
14
Esempio 4
La funzione:
template <class T> T & minimo(const T & a1, const T & a2) {
if(a1<=a2) { return a1; } else { return a2;}
}
E il suo uso:
#include <TwoVector.h>
int main()
{
float a = min(3.,2.); //float
int i
= min(2,3);
// int
TwoVector p1(1.,2.);
TwoVector p2(3.,1.);
TwoVector p3 = min(p1,p2);
return 0;
}
#include “mymin.icc”
15
Libreria STL
1. Riferimenti
http://wwweth.cern.ch/STL_doc/
16
container
•
Strutture dati per memorizzare oggetti (e puntatori ad oggetti)
Esempi di contenitori
vector
list
map
•
Per accedere ad essi (iteratori)
•
Per eseguire operazioni su di essi ( find, sort, copy, merge… )
17
Funzionamento di vector
begin()
++
end()
0
1
2
...
9
p
p
p
p
p
push_back()
p
18
Uso di vector
Main.cc
#include <stdlib.h>
#include <vector>
int main() {
vector<int> v; // create an empty vector of integers
cout << v.size() << endl; // print the size of v: zero
for (int I=0; I!=10; ++I) { // a loop from 0 to 9
v.push_back(I); // add an integer to v from the back
}
cout << v.size() << endl; // print the size of v: 10
// create an constant iterator for a vector of integers:
// p behaves at all effects as a “const int *”
vector<int>::const_iterator p;
//
begin() points to the first element
// and end()
to the last+1
// (compare with the previous “for” loop)
for (p=v.begin(); p!=v.end(); ++p) cout << (*p) << “ “;
cout << endl;
return 0;
}
19
Scarica

ppt - Università degli Studi Roma Tre