Elementi di
programmazione
ad oggetti
a. a. 2009/2010
Corso di Laurea Magistrale in Ingegneria Elettronica
Docente: Mauro Mazzieri, Dipartimento di Ingegneria Informatica,
Gestionale e dell’Automazione
Lezione 7
Template
Programmazione generica

La programmazione generica utilizza i
tipi come parametri
Consentono di definire famiglie di
funzioni o di classi, che differiscono sulla
base di tipi su cui operano
 Il compilatore genera una
specializzazione per ogni combinazione
di tipi usata

 La
programmazione generica consente di
generare automaticamente del codice a
partire da definizioni generali
Template di funzione


Le funzioni sovraccaricate realizzano
funzionalità analoghe su dati diversi
I template servono ad effettuare le stesse
funzioni su dati diversi



Forniscono un meccanismo con cui è possibile
preservare la semantica delle funzioni e delle
chiamate di funzioni
Consentono di generare automaticamente
istanze dello stesso algoritmo che operano su
dati diversi
Una funzione viene solitamente definita come
template quando la sua implementazione
rimane invariata per un insieme di tipi di dato
diversi gestiti
Definizione di template



template <class T>
template <class Item, class Value>
template <typename T>

segue la definizione della funzione
Es.
template <class T> T minore(T a, T b) {
return a < b ? a : b;
}

int main() {
cout << minore(10, 20);
cout << minore(2.45, 1.14);
}
Definizione di template

La parola chiave template è sempre
posta all’inizio di una dichiarazione ed
una definizione di template
È seguita da una lista di parametri
racchiusi tra < e > e separata da virgole
 La lista di parametri non può essere
vuota
 Un parametro può essere costituito

 Da
un tipo
 Da un valore costante
Template di classe

I membri di una classe generica sono
dichiarati e definiti esattamente come
per le classi non generiche


Se un membro è definito esternamente,
deve essere esplicitamente dichiarato
come template
Sono molto usati per definire una
serie di manipolazioni (contenitore,
algoritmi) su dati specificati dal
parametro di tipo
Template di classe


Un template di classe è un classe con uno o più parametri di tipo
L’uso tipico è per i contenitori

Li si vuole rendere indipendenti dal tipo di oggetto effettivamente
contenuto
template<class C> class Sequenza
{
C* s;
int size;
int n;
public:
Sequenza();
Sequenza(const C*);
Sequenza(const Sequenza&);
~Sequenza(void);
C operator[](int) {
return s[i];
}
};

Non è possibile sovraccaricare il nome di una classe template
Template di classe

Un template di classe può avere i
membri static
Ogni specializzazione ha i propri membri
 Un membro condiviso va messo in una
classe base non template

I template di funzione possono essere
funzioni membro
 Un template di classe può avere come
membri dei template di funzione

Template con costanti

Un parametro di template può essere costituito da
una costante


Costanti di tipo intero possono essere utilizzate per
fornire dimensioni o limiti
template <class C, int maxsize> class
Buffer {
C v[maxsize];
int size;
// …
}
Si può usare un parametro di template per definire i
successivi parametri
template <class C, int dim, C val> bool
sottoSoglia(C v[dim]) {
for (int i = 0; i < dim; i++)
if (v[i] < val)
return true;
return false;
}
Esempio: template con costante
template <typename T, int size> T minore(T
(&v)[size]) {
T result = v[0];
for (int i = 1; i < size; i++)
if (v[i] < result)
result = v[i];
return result;
}
int main()
{
int a[] = {1, 2, 3, 4};
double b[] = {0.3, 0.8, 7, 12, 0.1};
cout << minore(a) << endl;
cout << minore(b) << endl;
return 0;
}
Deduzione degli argomenti di
un template

Quando viene chiamato un template di
funzione, i tipi ed i valori degli argomenti
sono determinati sulla base dei tipi e valori
della argomenti


I tipi degli argomenti non devono
corrispondere esattamente, ma le uniche
conversioni possibili sono




Specializzazione del template
Da Lvalue a Rvalue, da array a puntatore, da
funzione a puntatore
Conversioni di qualificazione const
Da classe a classe base
Non è possibile sovraccaricare il nome di
una classe template
Tipi dei parametri

Un template dipende solo dalle
proprietà dei tipi di parametri
Non richiede che i tipi utilizzati come
argomenti siano esplicitamente correlati
 In particolare, non richiede che
appartengano ad una specifica gerarchia
di ereditarietà

Specializzazione

Consente di definire implementazioni
alternative per un template
template<class C> class Sequenza { //… }
// specializzazione
template<> class Sequenza<int> { //… }

Nelle specializzazione sono tolti dalle <>
i parametri per cui si fa la
specializzazione
 Possibile
specializzazione parziale
Specializzazione e
implementazione comune

Una specializzazione può servire a
creare un’implementazione comune
per una famiglia di parametri di tipo
// template di contenitore generico
template<class C> class Vector { //… }
// specializzazione di contenitore di
puntatori a void
template<> class Vector<void*> { //… }
// specializzazione per tutti i puntatori
template<class C> class Vector<C*> : private
Vector<void*> { //… }
Sovraccarico dei template di
funzione
Le specializzazioni generate a partire da un
template vengono chiamate utilizzando la
risoluzione dei sovraccarichi
Il template di funzione può essere sovraccaricato


Da altri template che differiscono per numero di
parametri
Da funzioni senza template



Risoluzione del sovraccarico:
1.
2.
3.
Tentativo di risoluzione con funzione senza template
Se fallisce, il compilatore cerca un template di funzione
e se lo trova genera e utilizza la specializzazione
Se non trova ancora alcuna corrispondenza o se ci
sono corrispondenze multiple, errore
Ereditarietà e template

È possibile derivare una classe template da
una classe tradizionale


Si può derivare una classe template da
un’altra classe template


Si fa per esempio per fornire una
implementazione comune
Es. derivare da Vector<T> una
CheckedVector<T> che effettua controlli sugli
indici
I template di classe forniscono
un’interfaccia comune ad una famiglia

Sono una forma di polimorfismo


Polimorfismo dinamico: funzioni virtuali
Polimorfismo statico o parametrico: template
Nota finale

È generalmente opportuno effettuare
il debug di un funzione o classe su di
un tipo concreto, prima di renderla
generica
Scarica

Lezione 7