160 likes | 275 Views
La programmation générique avec la STL. EIUMLV - Informatique et Réseaux 99. Benoît ROMAND. Ce dont on va parler:. Les concepts de généricité : re-encore à nouveau un autre rappel, mais ça finira par rentrer! La Standard Template Library
E N D
La programmation génériqueavec la STL EIUMLV- Informatique et Réseaux 99 Benoît ROMAND
Ce dont on va parler: • Les concepts de généricité : re-encore à nouveau un autre rappel, mais ça finira par rentrer! • La Standard Template Library avec les concepts, des exemples, et tout ce qui va bien • Enfin:les trucs qu’il faut comprendre ( ou en tout cas retenir ) pour le projet
Programmation générique: les motivations • La principale: la flemme • La réutilisation du code ( cf. premier point ) • La facilité d’écriture • La lisibilité du code • …
Algorithmes Containers Itérateurs The schéma, par Stepanov et Lee • Les algorithmes sont indépendants du type de données stockées • Il s’agit ainsi de connecter des algorithmes à des structures de données, par le biais de connecteurs.
La STL • Application directe des concepts développés par Stepanov • Il s’agit d’une bibliothèque d’algorithmes généraux et de structures de données: Des containers - de séquence - associatifs Des algorithmes - sort, find, search, … - copy, swap, for_each, … Des itérateurs adaptés aux types de container
STL - Les containers de séquence • Vector - extensible et relocalisable - accès aléatoire par index en O(1) - insertions et retraits à la fin en O(1) - insertions et retraits lents au milieu • List ( liste circulaire doublement chaînée ) - insertions et retraits n’importe où en O(1) - accès au début et à la fin en O(1) - accès lent aux autres éléments • Deque ( Double Ended Queue = tampon circulaire dynamique ) - exactement pareil que Vector pour la complexité - pas d’insertion au milieu - bon compromis vitesse d’accès / souplesse du remplissage
STL - Les containers associatifs • Set ( liste triée ) - Chaque élément doit être unique ( pas de doublons ) - accès aléatoire par clé ( l’objet lui-même est la clé ) • Multiset - Un ‘set’ qui permet les doublons • Map ( association clé / élément ) - une clé pour un élément ( pas de doublons ) - accès aléatoire par clé • Mulimap - Un ‘map’ ou les éléments peuvent être multiples pour une clé
STL – Les itérateurs • L'itérateur est une généralisation des pointeurs. . Il permet de parcourir en séquence les éléments d'un conteneur. • Hiérarchie des itérateurs: Lecture Ecriture Forward It++ Bidirectionnel It++, It-- Accès aléatoire It+n, It-n
STL – petits exemples (1)La copie void main() { list<int> l(4,0); // l vaut 0::0::0::0::[] vector<int> v(10,1); // v vaut [1,1,1,1,1,1,1,1,1,1,1] vector<int>::iterator i = copy(l.begin(),l.end(),v.begin()); copy(v.begin(),i, ostream_iterator<int>(cout," ")); copy(i,v.end(), ostream_iterator<int>(cout," ")); }
STL – petits exemples (2)Le tri #include <iostream> #include <list> #include<algorithm> List<char> initC(char*c) { List<char> majax; while (*c != ‘\0’= majax.push_back(*c++); return majax; } void main() { List<char> gerard = initC("le plus grand et le plus fort des magiciens"); gerard.sort(); gerard.unique(); for (List<char>::iterator i = gerard.begin() ; i != gerard.end() ; i++) cout << *i; }
STL – Autre notion : l’adaptateur (1) • Adaptateur de container Pour résumer : Adaptateur < Conteneur < Truc > > • Stack ( la pile ) Peut être implémentée avec Vector, List, Deque Principe LIFO : push et pop à la même extrémité • Queue ( la file ) Peut être implémentée avec List, Deque Principe FIFO • Priority_queue ( la file par priorité ) Dépend d’une fonction de comparaison: priority_queue< Conteneur < Truc > , fcomp < Truc > >
STL – Autre notion : l’adaptateur (2) void main() { int arr[] = {1,4,9,16,25}; list<int> liste(arr, arr+5); list<int>::reverse_iterator revit; revit = liste.rbegin(); while (revit != liste.rend()) cout << *revit++; } • Adaptateurs d’itérateurs • L’itérateur inverse
STL – Autre notion : l’adaptateur (3) void main() { int t1[] = { 1, 3, 5, 7, 9}; deque<int> dq1(t1,t1+5); int t2[] = { 2, 4, 6}; deque<int> dq2(t2,t2+3); copy(dq1.begin(), dq1.end(), back_inserter(dq2)); for (int i=0 ; i<dq2.size() ; i++) cout << dq2[i] << ‘ ‘; } • L’itérateur d’insertion
STL – pour finir : les foncteurs • Abstraction de la notion de fonction. • Foncteur = Objet dont la classe définit l’opérateur () , appelé opérateur de fonction • Permettent d’appliquer des fonctions sur les objets manipulés #include <iostream> #include <functional> template <class T, class F> T applique(T i, T j, F foncteur) { return foncteur(i, j); } void main(void) { plus<int> foncteur_plus; cout << applique(2, 3, foncteur_plus) << endl; }
Parlons voir de Ookce… • 1 : les concepts de généricité ne s’appliquent pas seulement au c++… • 2 : on a le droit de les appliquer • 3 : le joli schéma de Stepanov peut être généralisé : on sait à quoi ressemble l’objet avec lequel on veut discuter et ce qu’il doit faire, mais on ne sait pas comment il fait ce qu’il fait ( et on plus ce n’est pas notre problème ) En gros, si l’objet cible change, on lui demande simplement de garder la même apparence. Comme ça, on n’a pas besoin de recommencer tout notre code • 4 : c’est très chiant au début, mais ça facilite la vie après