Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
-2-
C e C++
-3-
Filosofia
C++:
compatibilit con il C,
prestazioni,
potenza
Java:
semplicit,
robustezza,
portabilit
-4-
template
ereditariet
prestazioni
semplice e multipla
possibilita di mascherare
linterfaccia dellantenato
espressivit
Sovraccaricamento operatori
-5-
#include<iostream.h>
#include <string>
main()
{
int i=3;
string s1("hello");
if (i < 0)
{
float x(6.8);
string s2("negative");
x = -i;
cout << x;
cout << s2<<\n;
}
cout << i<<\n;
cout << s1<<\n;
nota
// costruttore per i
// costruttore per s1
// costruttore per x
// costruttore per s2
// distruttore per x e s2
// distruttore per i e s1
-7-
assegnare un oggetto ad un
altro corrisponde al copiarne
lo stato
dopo lassegnamento
#include<iostream.h>
#include <string>
main()
{
string s1("hello");
string s2("bye");
cout<<s2<<endl;
s2=s1;
s2[0]=H;
cout<<s1<<endl;
cout<<s2<<endl;
}
-8-
per indirizzo:
void modifica(string &s)
#include<iostream.h>
#include <string>
void modifica(string s){
s[0]= H;
}
main()
{
string s1("hello");
cout<<s1<<endl;
modifica(s1);
cout<<s1<<endl;
}
output
-9-
Array di oggetti
Data
+ int giorno
+ int mese
+ int anno
conferenze:
21
5
1998
7
3
1996
- 10 -
il tipo puntatore
gli operatori new e delete
p=&i;
1233
10
1234
i
p
1234
1235
1236
1237
- 11 -
puntatore allintero
memorizzato in k
#include<iostream.h>
#include <string>
main()
{
int *i;
int k=5;
int *j=&k;
string *s;
allocazione
dinamica di un
intero
liberazione della
memoria allocata
dinamicamente
i=new int;
*i=5;
s=new string("pippo");
cout<<*s<< <<*i;
delete s; delete i;
puntatore ad intero
allocazione dinamica
di una stringa
}
- 12 -
attenzione !
int *p;
int vettore[10];
p = vettore;
*p = 1;
p++;
*p = 2;
cout << vettore[0]
<< vettore[1];
}
- 13 -
Data
d1 =
d2 =
d1 =
d1
d2
+ 26
+1
+ 1999
+ 27
+1
+ 1999
*d1, *d2;
new Data(26, 1, 1999);
new Data(27, 1, 1999);
d2;
d1
d2
- 14 -
Stringa
puntatori
- char *caratteri
- int numeroCaratteri
~Stringa() {
delete(caratteri); }
int main()
{
Stringa s1(10);
Stringa s2(20);
s1 = s2;
// errore: si
// dealloca 2
// volte s2.p !!!
s1
78
78
10
10
s2
215
s1 = s2
78
20
10
s2
215
215
215
20
s1
215
20
20
20
- 15 -
Classi
Esempio
#include <stdlib.h>
#include <stdio.h>
class string {
private:
char* s;
main() {
string s1("hello"), s2("there");
s1.print();
s2.print();
}
public:
string(const char* s = "");
~string() { free(s); }
void print() const {
printf("%s\n",s);
}
nota:
};
distruttore
uso del C
metodi inline
separazione tra dichiarazione
e implementazione
parametri const
metodi const
- 17 -
Aggregazione
#include <iostream.h>
class Data {
int giorno; int mese; int anno;
public:
Data(int g=0, int m=0,int a=0):
giorno(g), mese(m), anno(a) {;};
};
class Appuntamento{
Data giorno;
string motivo;
public:
Appuntamento(int g, int m, int a, char * mot):
giorno(g,m,a), motivo(mot) {;};
};
main(){
Appuntamento imp(12, 5, 97, "riunione");
}
lista di inizializzazione
parametri di default
- 18 -
Aggregazione
main(){
Appuntamento imp(12, 5, 97, "riunione");
}
imp.giorno:
imp:
12
5
97
riunione
- 19 -
Amicizia
class Pluto
{
//...
friend class Pippo;
friend int funzioneAmica();
friend char Tom::metodoAmico();
//...
}
- 20 -
Overloading operatori
grazie alloverloading
gli oggetti possono
essere trattati come i
tipi primitivi
attenzione alla
semantica che si
associa alloperatore
si rischia di confondere
lutilizzatore della classe
esempio di operatori:
- + += = == ++ [ ]
< << ! cast * ->
class Data {
//...
public:
int operator < (const Data& d);
};
void main()
{
Data a, b;
//...
if (a < b)
cout << a pi vecchio di b <<endl;
};
- 22 -
class Complex {
{
Complex temp (re + c2.re, im + c2.im);
double re;
double im;
return temp;
}
public:
Complex(double reale = 0, double imm = 0) {
re = reale;
im = imm;
};
};
nota:
metodi const
- 23 -
main()
{
Complex c1(3.0);
Complex c2(1.0, 2.0);
c1.Stampa();
c2.Stampa();
Complex c3 = c1 + c2;
c3.Stampa();
c3=c2+7; // FUNZIONA??
c3=7+c2; // NO!
}
- 24 -
controindicazione:
potrebbe essere necessario rendere loperatore
friend della classe
#include <iostream.h>
void main()
{
double reale;
int intero;
cout << \nFornire un valore reale: ;
cin >> reale;
cout << \nFornire un valore intero: ;
cin >> intero;
cout << \n\nReale: << reale << endl;
cout << Intero: << intero << endl;
}
- 26 -
class Complex {
double re, im;
public:
Complex(double reale = 0, double imm = 0) {
re = reale; im = imm;
};
Complex operator + (const Complex& c2) const{
int main()
{ Complex c1(3.0); cout<<c1;}
loperatore <<
non un
metodo
spesso deve
essere reso
amico della
classe
- 27 -
Ereditariet semplice,
polimorfismo e binding
Ereditariet
#include<iostream.h>
class Veicolo {
public:
void mess() {cout << "Veicolo Generico" << endl;}
};
Veicolo
+ mess()
VeicoloPrivato
+ mess()
VeicoloCommerciale
+ mess()
- 29 -
giustificazione output:
vehicle=&mycar;
vehicle->mess();
vehicle=&myvan;
vehicle->mess();
}
output
Veicolo Generico
Veicolo Generico
- 30 -
output
perch nellinvocazione
di f(mycar) non stato
utilizzato il binding
dinamico ?
il metodo era
cos definito:
void f(Veicolo v) {
v.mess();
}
Veicolo Privato
Veicolo Commerciale
Veicolo Generico
- 32 -
main(){
Veicolo generico;
VeicoloCommerciale commerciale;
+ int targa
+ mess()
generico.targa=1556;
commerciale.targa=9888;
commerciale.peso=1000;
VeicoloCommerciale
+ int targa
+ int peso
generico.mess();
commerciale.mess();
output
generico=commerciale;
generico.mess();
}
+ mess()
void f(Veicolo v) {
v.mess();
}
- 34 -
in C++ possibile
nascondere uno o pi
elementi pubblici del padre
lesigenza di eliminare un
metodo in una sotto classe
normalmente indica un
cattivo progetto della
gerarchia di classi
Errore in compilazione!
#include<iostream.h>
class Veicolo {
public:
virtual double velocitaDiVolo() const {return 12;};
};
class VeicoloTerrestre : public Veicolo {
virtual double velocitaDiVolo() const {return 0;};
public:
};
main(){
VeicoloTerrestre *vt = new VeicoloTerrestre;
Veicolo *v=new Veicolo;
cout<< vt->velocitaDiVolo()<<endl;
cout<<v->velocitaDiVolo()<<endl;
}
- 35 -
- 37 -
Le tre varianti
di eredit semplice
protected
private
private
public
public
protected
protected
protected
protected
private
non accessibile
non accessibile
private
non accessibile
- 38 -
Si perde il polimorfismo
polimorfismo e
binding dinamico
sono persi
ereditariet di
codice ma NON di
interfaccia: le due
classi coinvolte
definiscono due tipi
indipendenti
ERRORE IN
COMPILAZIONE
#include<iostream.h>
class Veicolo {
public:
virtual double velocitaDiVolo() const {return 12;};
};
class VeicoloTerrestre : protected Veicolo {
public:
virtual double velocitaDiVolo() const {return 0;};
};
main(){
VeicoloTerrestre *vt = new VeicoloTerrestre;
Veicolo *v;
cout<<vt->velocitaDiVolo()<<endl;
v=vt;
cout<<v->velocitaDiVolo()<<endl;
}
- 39 -
Ereditariet multipla
Ereditariet multipla
permette di creare classi ibride che ereditano membri da due o pi
classi. Esempio:
class Venditore {
protected:
char zona[50];
};
class Manager {
protected:
int livello;
};
Venditore
Manager
Mgr_Vendite
Eredita da
entrambi i suoi
ascendenti, quindi
contiene sia
zona[50] che
livello
- 41 -
class Base2 {
//...
public:
int doppione;
//...
};
//...
public:
int doppione;
//...
};
main(){
Derivata d;
d.Base1::doppione=7;
d.Base2::doppione=3;
cout<<d.totale()<<endl;
}
class Base2 {
public:
int doppione;
};
class Derivata : public Base1, public Base2 {
public:
int totale(){
return Base1::doppione + Base2::doppione;
}
};
- 43 -
class Impiegato {
protected:
char nome[30];
};
class Venditore : public Impiegato {};
class Manager : public Impiegato {};
class MgrVendite : public Venditore, public Manager {};
Impiegato
Impiegato
Venditore
Manager
Mgr_Vendite
- 44 -
Ereditariet multipla:
classi base virtuali
class Impiegato {
protected:
char nome[30];
};
class Venditore : virtual public Impiegato {};
class Manager : virtual public Impiegato {};
class MgrVendite : public Venditore, public Manager {};
Vede una sola volta Impiegato
tra i suoi ascendenti, quindi
eredita una sola volta il campo
nome[30]
Venditore
Manager
Mgr_Vendite
- 45 -
Template
Genericit
Macro
Classi astratte
Template
- 47 -
Il concetto di
genericit
- 48 -
// Lista.h
Vantaggi / svantaggi
Lista.h
class Lista {
TYPE dati[50];
// ...
};
// Main.cpp
// ...
Lista ListaInteri;
// ...
- 49 -
GenericObject
- 50 -
funziona, ma:
intStack.Push(new IntObject(78));
cout << ((IntObject *) intStack.Pop())->data;
cout << ((IntObject *) intStack.Pop())->data;
Stack floatStack;
floatStack.Push(new FloatObject(1.3));
cout << ((FloatObject *) floatStack.Pop())->data;
}
- 51 -
- 52 -
Funzioni template
#include <iostream.h>
template <class Tipo>
Tipo max(const Tipo &a, const Tipo &b) {
return (a > b) ? a : b;
}
main() {
double d1 = 1.2, d2=5.6;
int r1(15), r2(5);
cout<<"Il valore maggiore tra: " << d1 << " e "<< d2 <<" " << max(d1,d2) << endl;
cout<<"Il valore maggiore tra: " << r1 << " e " << r2 <<" " << max(r1,r2) << endl;
int i=max(r1,d2);
cout << i << endl;
funziona??
- 53 -
- 54 -
Template per
classi generiche
Dichiarazione di una
classe generica
Definizione di un metodo
generico
Definizione di unistanza
della classe generica
Vettore<int> vet(5);
- 55 -
return data[--num];
}
data[num++] = elem;
}
Stack.cpp
}
- 57 -
while ( ! intStack.Empty() ) {
cout << intStack.Pop() << endl;
#include Stack.cpp
main(void) {
Stack<int> intStack;
intStack.Push(25);
intStack.Push(12);
Complex c1(3.0, 2.0), c2(1.0, -3.0);
main.cpp
Stack<Complex> complexStack;
complexStack.Push(c1);
complexStack.Push(c2);
Nota
- 58 -
esempio:
template <class T> T max(T a, T b) { return ( (a > b) ? a : b ); }
Complex c1, c2;
Complex c3 = max(c1, c2); // Errore !!!! Complex non
// definisce loperatore >
soluzione:
- 59 -
N.B.: i parametri del template che non sono tipi devono essere delle
costanti
- 60 -
Template e polimorfismo
a confronto
- 61 -
Template e polimorfismo
a confronto
Template e polimorfismo
a confronto
- 63 -
Eccezioni
Eccezioni
- 65 -
Organizzazione
dei file di un
programma C++
Stile di programmazione
- 67 -
Relazione di inclusione
Immagine.cpp
Immagine.h
prima di linkare il
programma necessario
assicurarsi che tutti i moduli
modificati siano stati
ricompilati
main.cpp
Triangolo.cpp
Triangolo.h
il meccanismo delle
inclusioni crea dipendenze
non banali
Punto.cpp
Punto.h
#endif
- 68 -
Standard Template
Library
STL - storia
- 70 -
Contenitori
(lista, array, coda)
Tipi
(char, int, double)
algoritmi, tipi e
contenitori sono tre
dimensioni
indipendenti
un contenitore pu
contenere qualsiasi
tipo
un algoritmo si applica
a qualsiasi contenitore
- 71 -
STL
contenitori
contenitori che racchiudono oggetti, come vettori, insiemi e code(sono
classi template)
iteratori
algoritmi
- 72 -
Contenitori
- 73 -
Contenitori
sequenziali
organizzano un insieme finito di oggetti dello stesso tipo in modo
strettamente sequenziale
associativi
forniscono la possibilit di accedere velocemente ai dati in base al
valore di chiavi
adattatori
incapsulano un contenitore per fornirne una interfaccia diversa
Contenitori
Iteratori
corrispondono a java.util.Enumeration
- 76 -
Iteratori
Pi semplici
Input e Output
Forward
Bidirectional
Random access
(minori funzionalit)
Pi potenti
(inglobano le
funzionalit dei
precedenti)
- 77 -
Esempio
tipico utilizzo di un contenitore
#include <vector>
using namespace std;
shape
int main() {
draw( )
vector<shape*> shapes;
shapes.push_back(new circle);
shapes.push_back(new square);
shapes.push_back(new triangle);
for(vector<shape*> ::iterator i = shapes.begin();
circle
triangle
square
i != shapes.end(); i++)
(*i)->draw();
for(vector<shape*> ::iterator j = shapes.begin();
j != shapes.end(); j++)
delete *j;
return 0;
in Java avremmo scritto:
}
for(Enumeration i = shapes.elements();i.hasMoreElements();)
i.nextElement().draw();
- 78 -
Algoritmi
funzioni template studiate per essere applicate a qualsiasi
contenitore
quattro categorie:
-1-
-2-
-3-
-4-
- 79 -
Esempio: ordinamento
#include <vector>
#include <algo.h>
#include <iostream.h>
int main() {
vector<int> v(3);
vector<int>::iterator first = v.begin();
vector<int>::iterator last = v.end();
first = v.begin();
sort(first,last); //--ORDINAMENTO
v[0] = 5;
v[1] = 2;
v[2] = 7;
}
Riferimenti STL
- 81 -
STL e JDK
STL
JDK