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 10.4
La libreria standard: iteratori e allocatori.
Iteratori

L’iteratore è un’astrazione della nozione di
puntatore ad un elemento di un array

Non c’è nessun iteratore “NULL”


Un iteratore fa riferimento ad un elemento valido se è
diverso dall’iteratore che segnala la fine della
sequenza
Un iteratore valido può essere dereferenziato
con *, ->, []

Un iteratore può non essere valido perché non è stato
inizializzato, oppure il contenitore a cui fa riferimento
è stato ridimensionato o distrutto, o infine se si tratta
del demarcatore di fine sequenza
Categorie di iteratori

Gli iteratori vengono classificati sulla base delle
operazioni che consentono di effettuare in tempo
costante







Complessità O(1)
Ingresso (In): solo letture e avanzamento
Uscita (Out): solo scrittura e avanzamento
In avanti (For): come In e Out insieme
Bidirezionali (Bi): come For, ma consentono di scorrere la
sequenza anche all’indietro
Ad accesso casuale (Ran): consentono l’accesso
indicizzato
Non sono delle classi con una nozione di
ereditarietà

Se es. un template della libreria standard ha come
argomento di tipo “In”, si presuppone che si tratti un
iteratore che supporta operazioni di lettura ed
avanzamento
Operazioni su categorie di iteratori
Out
In
For
Bi
Ran
lettura
= *p = *p = *p = *p
accesso
scrittura
->
->
->
-> []
*p = *p = *p =
iterazione ++
++
++
++
--
confronto
==
!=
==
!=
==
!=
*p =
++ -+ - +=
-=
== !=
< >
<= >=
const e non const

Indipendentemente dalla loro
categoria, gli iteratori possono essere
const o non const
Distanza tra iteratori


Solo gli iteratori ad accesso casuale
definiscono l’operatore –
La distanza tra iteratori può essere
calcolata mediante una funzione
template<class In>
int dinstance(In first, In last) {
int result = 0;
while (first++ != last)
d++;
return result;
}
iterator_traits

Il tipo di ritorno di difference() non
dovrebbe essere int ma
In::difference_type


tipo numerico con segno in grado di
contenere la differenza tra iteratori
… non funzionerebbe però con i
puntatori
iterator_traits

La libreria standard definisce un template
iterator_traits, che contiene tra l’altro:
template<class I>
struct iterator_traits {
typedef typename I::difference_type
difference_type;
};

Si può usare iterator_traits<I>::difference_type
anche su puntatori perché viene definita una
specializzazione per i puntatori
template<class T>
struct iterator_traits<T*> {
typedef ptrdiff_t diffference_type;
};
 la differenza tra puntatori viene rappresentata dal tipo
ptrdiff_t dichiarato in <cstddef>
Inseritori


Una sequenza di destinazione deve essere valida e
sufficientemente capiente
Per poter avere come destinazione un iteratore
che sottintende dei nuovi elementi che vengono
inseriti, nella libreria standard vengono definiti tre
classi template di iteratori e tre funzioni che ne
semplificano l’uso
template <class C> back_insert_iterator<C>
back_inserter(C& c);
template <class C> front_insert_iterator<C>
front_inserter(C& c);
template <class C, class Out> insert_iterator<C>
inserter(C& c, Out o);

Consentono l’uso es. di copy(v.begin(), v.end(),
back_inserter(l)) per ocpiare il contenuto del vector v in
coda alla lista l
reverse_iterator

i contenitori standard forniscono i
metodi rbegin() e rend() per ottenere
degli iteratori che scorrono la
sequenza all’incontrario

Partendo da rbegin(), con applicazioni
successive dell’operatore ++ si va dalla
fine all’inizio del contenitore
Iteratori e I/O

È possibile costruire un iteratore che
opera su un certo tipo di dato e
applicarlo ad un flusso
ostream_iterator<string> oo(cout);
*oo = “Salve ”;
oo++;
*oo = “e buona giornata”;
 istream_iterator<string> ii(cin);

 l’istream_iterator
predefinito indica la fine
del flusso, es.
istream_iterator<string> eos;
Allocatori


Un allocatore fornisce un metodo per allocare e
deallocare memoria
La libreria standard definisce in <memory> un
allocatore standard che fa uso degli operatori
predefiniti new() e delete
template<class T> class std::allocator {
typedef size_t size_type;
typedef T* pointer;
typedef const T* const_pointer;
pointer allocate(size_type n,
allocator<void>::const_pointer hint = 0);
void deallocate(pointer p, size_type n);
}
Scarica

Lezione 10-4