La libreria standard C++

Autore: Matteo Lucarelli
ultima versione su: matteolucarelli.altervista.org
Documento in costruzione

La libreria standard C++ (nel seguito libstdc++), parte integrante della definizione del linguaggio, include ed estende la libreria standard C (libc). In particolare include la Standard Template Library (STL), nata come componente aggiuntivo, che utilizza estensivamente le tecniche della programmazione generica.

Generalità

La libstdc++ è costituita da un vasto numero di classi e funzioni che trattano di:

Le funzionalità della libc possono essere richiamate tramite due convenzioni relative agli header files cioè direttamente oppure tramite la convenzione C++ ovvero senza .h ma con la lettera c davanti (ad esempio stdio.h diventa cstdio)

Tutte le definizioni della libstdc++ sono contenute nel namespace std, motivo per cui la maggior parte dei programmi iniziano con la direttiva:

using namespace std;
in caso contrario i simboli andranno qualificati con il prefisso std::.

La programmazione generica

Tramite la tecnica della programmazione generica è possibile definire ed implementare delle parti di codice indipendenti dai tipi di dati trattati, accedendo così ad un superiore livello di astrazione del codice con reali vantaggi sulla sua riutilizzabilità.

Facciamo notare che l'istanza del codice definito in modo generico avviene staticamente, cioè durante la compilazione, quindi:

A proposito dell'ultimo punto, per ovviare l'evidente problema di indipendenza, è stata introdotta una nuova parola chiave: export, che utilizzata come specificatore nella definizione di una funzione template ne permette la compilazione indipendente, demandando al linker la generazione delle istanze tipizzate necessarie. L'uso della specifica export non è però attualmente molto diffuso.

Il codice di una funzione che restituisca il massimo tra due generici argomenti può ad esempio essere scritto:

template <typename T> T max(T x, T y)
{
    return x > y ? x : y ;
}
dove la dichiarazione template comunica al compilatore che la successiva dichiarazione di funzione utilizza un generico tipo T che sara` noto solo al momento dell'effettivo utilizzo del codice. La parola chiave typename, introdotta ad hoc, può in questo uso essere sostituita dalla parola chiave class. Typename serve però anche a qualificare esplicitamente un tipo astratto, nel caso in cui il compilatore non possa dedurlo da sè:
typename T oggettoDiTipoT;

L'utilizzo di una funzione generica non comporta in generale alcuna differenza con una analoga funzione tipizzata, in quanto il tipo corretto può in gegerale essere dedotto dal compilatore dal tipo degli argomenti passati, e viene quindi istanziato automaticamente senza richiedere alcuna specifica aggiuntiva. Nel caso in cui non sia possibile dedurlo dal contesto (ovvero dai parametri) andrà invece specificato al momento della chiamata:

int ret=max<int>(5,7);

Una classe template viene definita in modo analogo ad una funzione:

template <class T1> class ListaGenerica {
	// .. 
	// definizione di membri e proprietà
	// che utilizzano il tipo generico T1
	// ad esempio:
	public:
		T1 getPar();
};
Mentre nell'implementazione è necessario specificare per ogni metodo che si tratta di un template, ad esempio il l'implementazione della funzione getPar sarà:
template <class T1> T1 ListaGenerica<T1>::getPar(){
	// .. corpo della funzione ..//
}
Al momento dell'istanza andrà quindi specificato il tipo da utilizzarsi in luogo del tipo generico:
ListaGenerica<float> listaFloat;
e nel seguito l'oggetto istanziato sarà utilizzabile come sempre.

Con le classi generiche, ma non con le funzioni, è possibile definire il tipo di default, da utilizzarsi in caso di mancata specifica:

template <class T1=double>
Nell'istanza che voglia utilizzare i tipi di default le parentesi angolari andranno quindi lasciate vuote:
ListaGenerica<> listaDouble;

I tipi generici utilizzati in un template possono naturalmente essere più di uno:

template <class T1, class T1, class T3=double, >
Ed è anche possibile l'annidamento di tipi generici:
 Array< Array<int> >  arrayOfIntArray;
Si noti che lo spazio fra le parentesi angolari è necessario a non interpretarle come un operatore di shift.

I contenitori della Standard Template Library

La STL implemente una serie di oggetti contenitori generici, il cui contenuto può essere di qualsiasi tipo:

I contenitori sono oggetti generici, i loro argomenti però devo possedere alcune caraterisitiche:

Per poter accedere ai singoli elementi di un contenitore esiste l'oggetto iteratore , che astrae e generalizza il concetto di puntatore. Ad esempio:

// istanza di un iteratore a vettore di interi
vector<int>::iterator it;  

// punta l'iteratore al primo elemento di un vettore di interi
it = v_int.begin();

// passa al secondo elemento 
it++;

// estrae l'elemento
int num=*it;

// estrae l'elemento di 3 posizioni successivo
int n2 = it[3];

Tutti i contenitori ammettono i seguenti costruttori (c è un generico contenitore):

// costruttore di contenitore vuoto
c::c();

// costruttore di copia
c::c(const c& other);

// riversamento da un contenitore di altro tipo
c::c(Iter first, Iter last);
ed i seguenti metodi:
// ridimensiona ad n elementi
void c::resize(size_type n);

// ritorna la dimensione attuale
size_type c::size() ;

// true se il contenitore è vuoto
bool c::empty();

// ritorna la capacità massima
size_type c::max_size();
Tutti i contenitori sono dinamici, cioè allocano la memoria necessaria quando serve. L'oggetto vector permette, per ottimizzazione è la possibilità di riservare preventivamente una certa quantità di memoria tramite l'operazione:
void vector::reserve(size_type n);

Gli algoritmi della Standard Template Library

...TODO

La classe string

La classe string, messa a disposizione dal C++ non è, come in C, un vettore di caratteri ma è un contenitore di caratteri, molto simile a vector<char>. La maggior parte degli algoritmi della STL sono applicabili anche alla classe string.

...TODO

Input e Output

...TODO
matteolucarelli.altervista.org
©opyright info