Professional Documents
Culture Documents
a oggetti
Programmazione generica
a.a. 2015/2016
Francesco Fontanella
Programmazione generica
Consente la definizione di una classe (o
funzione) senza che venga specificato il tipo
di dato di uno o pi dei suoi membri (o dei
suoi parametri)
La sua utile quando il codice non dipende
dal tipo di dato da elaborare
Esempi:
ADT (pila, coda, ecc)
Algoritmi di ordinamento
Francesco Fontanella, Corso di Programmazione a Oggetti
a.a. 2015/2016
Templates
Le classi (funzioni) per i quali uno o + tipi di
dati non sono specificati sono dette:
templates
I templates definiscono delle classi
(funzioni) cosiddette generiche, o anche
parametriche,
Questo codice deve poi essere istanziato
dall'utente per produrre del codice che lavori
con specifici tipi di dato
Francesco Fontanella, Corso di Programmazione a Oggetti
a.a. 2015/2016
template<classT>
Tfunz(Tpar)
{
Tvar1,var2,varN;
.
.
.
returnvar1;
}
intmain()
{
inti;
floatf;
charc;
funz(i);
funz(f);
funz(c);
return0;
}
intfunz(intpar)
{
intvar1,var2,varN;
.
.
.
returnvar1;
}
floatfunz(floatpar)
{
floatvar1,var2,varN;
.
.
.
returnvar1;
}
charfunz(charpar)
{
charvar1,var2,varN;
.
.
.
returnvar1;
}
m=0;
for(i=1;i<n;++i)
if(v[i]>v[m])
m=i;
returnv[m];
}
intmain()
{
inti,vi[],n;
floatf,vf[];
charc,str[];
.
.
i=find_max(vi,n);
f=find_max(vf,n);
c=find_max(str,n);
return0;
}
Istanziare un template
Una volta definito, un template pu essere usato
specificando i tipi di dato da istanziare
Esempio
template<classT>
voidswap(T&x,T&y)
{Tt=x;
x=y;
y=t;
}
inti=3,j=4;
swap<int>(i,j);
.
.
floatf=4.0,g=5.0;
swap<float>(f,g);
Conoscendo i tipi degli
argomenti, il compilatore in
grado dinferire listanziazione
corretta
inti=3,j=4;
swap(i,j);// uses swap<int>
.
.
floatf=4.0,g=5.0;
swap(f,g);// uses swap<float>
Francesco Fontanella, Corso di Programmazione a Oggetti
a.a. 2015/2016
Templates di classi
template<classT>
classMyclass{
Tvar1,var2,varN;
.
.
Tfunz1()
voidfunz2(Tpar1,);
.
.
};
10
Parametri di un template
template<classT,intsize=100>
classVector{
Tv[size];
public:
T&operator[](inti);
Non tutti i parametri devono
};
essere tipi generici
template<classT,intsize=100>
T&Vector<T,size>::operator[](inti){
if(i>=0&&i<size);
returnv[i];
elsecerr<<endl<<ERRORE!;
}
Vector<int,50>ivect;
Vector<double>dvect;
Francesco Fontanella, Corso di Programmazione a Oggetti
a.a. 2015/2016
11
template<classT,classU>
classPair{
Tx1;
Un template pu avere uno o
Ux2;
pi parametri
public:
Pair(Ta1,Ua2):x1(a1),x2(a2){}
};
Pair<string,int>p1("deep",6);
cout<<p1.x1<<""<<p1.x2<<endl;
NOTA
Le funzioni membro di una classe template sono
istanziate solo se usate
Francesco Fontanella, Corso di Programmazione a Oggetti
a.a. 2015/2016
12
13
Stack::~Stack()
{
while(top)
pop();
}
intStack::pop(){
intv;
Nodo*tmp;
if(top){
v=top>get_value();
tmp=top;
top=top>get_next();
deletetmp;
returnv;
}elsecerr<<endl<<"ERRORE!";
}
Francesco Fontanella, Corso di Programmazione a Oggetti
a.a. 2015/2016
14
Stack generico
template<classK>classNodo{
public:
Nodo(Kv,Nodo*n):value(v),next(n){}
Kget_val(){returnvalue;}
Nodo*get_next(){returnnext;}
private:
Nodo*next;
Kvalue;
};
template<classT>classStack{
public:
Stack(){top=0;}
~Stack();
voidpush(Tval){top=newNodo<T>(val,top);}
Tpop();
private:
Nodo<T>*top;
Nodo va istanziato,
};
perch generico!
Francesco Fontanella, Corso di Programmazione a Oggetti
a.a. 2015/2016
15
template<classU>Stack<U>::~Stack(){
while(top)
pop();
}
template<classZ>ZStack<Z>::pop(){
Zv;
Nodo<Z>*tmp;
if(top){
v=top>getVal();
tmp=top;
top=top>getNext();
deletetmp;
returnv;
}elsecerr<<endl<<"ERRORE!";
}
NOTA
Per le diverse funzioni, anche di una stessa classe, posso usare
lettere diverse per i template e classi
Francesco Fontanella, Corso di Programmazione a Oggetti
a.a. 2015/2016
16
#include<stack.h>
intmain(){
Stack<int>si;
Stack<float>sf;
si.push(1);
sf.push(3.0);
cout<<endl<<si.pop();
cout<<endl<<sf.pop();
return0;
}
OUTPUT
> 1
> 3.0
17
Nodo Generico
#ifndefNODE_H
#defineNODE_H
template<classT>
classNode{
public:
//Costruttore
Node(Tx):next(0),value(x){}
//FunzioniGET
Node<T>*get_next()const{returnnext;}
Tget_value()const{returnvalue;}
//FunzioniSET
voidset_next(Node<T>*ptr){next=ptr;}
voidset_value(Tval){value=val;}
private:
Tvalue;
Node*next;
friendclassListIterator<T>;// Vedi dopo...
friendclassList<T>;
};
#endif
Francesco Fontanella, Corso di Programmazione a Oggetti
a.a. 2015/2016
20
Lista Generica
#ifndefLIST_H
#defineLIST_H
template<classT>
classList{
public:
List():n(0),l(0){};
~List();
voidappend(Tx);
constT&operator[](intpos)const;
intsize()const{returnn;}
protected:
Node<T>*l;
intn;
friendclassListIterator<T>;
};
21
//Overloadedintcast
operatorint(){returnm_nCents;}
L'overloading
intGetCents(){returnm_nCents;}
voidSetCents(intnCents){m_nCents=nCents;}
};
Francesco Fontanella, Corso di Programmazione a Oggetti
a.a. 2015/2016
sul casting
23
intmain()
{
Centsc(7);
inta;
a=c;
diventa
a=Cents::int(&c)
cout<<a;
return0;
}
24
if(ins){
diventa
.
.
if(ios::bool)
25
26
Incremento postfisso
dell'iteratore
Node<T>*operator++(inti)
{
Node<T>*tmp=0;
if(cur){
tmp=cur;
cur=cur>next;
}
returntmp;
}
Francesco Fontanella, Corso di Programmazione a Oggetti
a.a. 2015/2016
27
#include<iostream>
#include"List.h"
#include"ListIterator.h
constintmax=1000;
intmain()
{
List<int>list,i;
for(i=0;i<max;++i)
list.append(i);
// uso inefficiente!
for(i=0;i<MAX;i++)
cout<<list[i];
// iterazione efficiente
ListIterator<int>it(list);
while(it){
cout<<*it<<"";
it++;
}
return0;
}
28
Compilazione di template
Il compilatore non in grado di generare
codice oggetto quando vede una
definizione di template
Le istanze specifiche per un determinato
tipo, possono essere prodotte solo quando
i template vengono effettivamente utilizzati
29
30
32
demo.h
#ifndefDEMO_H
#defineDEMO_H
template<classT>intconfrontare(constT&,constT&);
// altre dichiarazioni
.
.
#include"demo.cpp"
#endif
demo.cpp
template<classT>intconfrontare(constT&a,constT&b)
{
if(a<b)
return1;
if(b<a)
return1;
return0;
}
// altre definizioni
.
.
Francesco Fontanella, Corso di Programmazione a Oggetti
a.a. 2015/2016
33
Osservazioni
scrivere una funzione generica implica
pensare in astratto, evitando le
dipendenze da tipi di dato, costanti
numeriche, ecc.
Una definizione di funzione template
solo un modello e non produce
effettivamente codice
Francesco Fontanella, Corso di Programmazione a Oggetti
a.a. 2015/2016
34
35