1 / 31

Cours n° 8 Conception et Programmation à Objets

Equipe pédagogique Marie-José Caraty, Denis Poitrenaud et Mikal Ziane. Cours n° 8 Conception et Programmation à Objets Réutilisation de composants de la bibliothèque standard du C++ (STL) 1/2. Sommaire. Introduction Conteneurs 1.1. Séquences élémentaires Conteneurs vector, deque, list

Download Presentation

Cours n° 8 Conception et Programmation à Objets

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Equipe pédagogique Marie-José Caraty, Denis Poitrenaud et Mikal Ziane Cours n° 8Conception et Programmation à Objets Réutilisation de composants de la bibliothèque standard du C++ (STL) 1/2

  2. Sommaire • Introduction • Conteneurs • 1.1. Séquences élémentaires • Conteneurs vector, deque, list • 1.2. Adaptateurs de séquence • Conteneurs stack, queue, priority_queue • 1.3. Conteneurs associatifs • Conteneur map, set, multimap, multiset • Itérateurs • Algorithmes • Manipulations - Ordonnancement • Recherche - Ensemblistes • Conclusion

  3. INTRODUCTION Standard Template Library (STL) • STL fournit les fonctionnalités de l'algorithmique de baseEnsemble de composants techniques • Types abstraits de données (TAD) correspondant aux structures de données classiques (implémentation abstraite des structures de données et de leurs méthodes associées)et d’algorithmes applicables aux TAD • Objectifs à la conception de STL • Structures de données et algorithmes doivent fonctionner pour tout type d'élément • type prédéfini/natif du langage • type utilisateur (défini par le programmeur) • Efficacité vitesse d'exécution • Abstraction de l'implémentation • Mécanisme de généricité • Fondé sur les patrons (templates) de classes, de méthodes et de fonctions • Normalisée en 1995 (ANSI Draft) • Source et documentationdisponible sur www.sgi.com/tech/stl/

  4. INTRODUCTION Composants phares de STL Conteneurs (container) Implémentation des structures de données les plus courantes avec leur allocation/désallocation mémoire automatique Itérateurs (iterator) Principes d'accès/balayage des éléments des conteneurs Algorithmes (algorithm) Implémentation d'algorithmes génériques associés itérateur algorithme conteneur

  5. 1. CONTENEURS Introduction • Implémentation générique de structures de données classiques en programmation • Organisation d’un ensemble fini d'éléments de même type • Conteneurs de séquence • Eléments organisés suivant un arrangement linéaire • Séquencesélémentaires (vector, deque, list) • Adaptateurs de séquence (stack, queue, priority_queue) • Conteneurs associatifs • Eléments décrits par des paires (clé, valeur) de type quelconque • et triés par ordre de clé • Recherche rapide (recherche binaire) d'élément(set, map, multiset, multimap)

  6. 1. CONTENEURS Classification Conteneurs list deque stack queue priority_queue map multimap set multiset Conteneursde séquence Conteneursassociatifs Adaptateursde séquence Séquencesélémentaires vector

  7. 1. CONTENEURS Visibilité des composants Inclusion des headers standards de la librairie STL #include <vector> // Définition de la classe vector #include <list> // Définition de la classe list #include <deque>// Définition de la classe deque #include <stack> // Définition de la classe stack #include <queue> // Définition des classes queue et priority_queue #include <map> // Définition de la classes map #include <multimap>// Définition de la classe multimap #include <set>// Définition de la classe set #include <multiset>// Définition de la classe multiset #include <algorithm>//Algorithmes génériques. Par exemple, copy(..) #include <iterator>// Définition de la classe iterator using namespace std;// Visibilité des entités déclarées dans la librairie // standard // Sans cette clause d'utilisation : utiliser // le nom qualifié // Préfixe suivi de l'opérateur de résolution de portée // Exemple : std::vector<int> V;

  8. 1.1. SEQUENCES ELEMENTAIRES Principes de fonctionnement Blocs contigus d'objets (vector) ou non contigus (deque, list) Insertion possible en tout point de la séquence Performance fonction du type de séquence et du point d'insertion Accès direct Insertion/suppression optimisée en fin vector deque Accès direct Insertion/suppression optimisée en début ou en fin (Double End QUEue) Accès séquentiel Insertion/suppression optimisée en tout point list

  9. 1.1 SEQUENCES ELEMENTAIRES Méthodes communes des séquences élémentaires (1/2) bool empty(); true si le conteneur est vide size_type size() const; Nombre d'éléments du conteneur size_type max_size() const; Contenance maximale du conteneur void resize(size_type, T c =T()); Redimensionnement du conteneur T& front(); Référence sur le premier élément T& back(); Référence sur le dernier élément

  10. 1.1. SEQUENCES ELEMENTAIRES Méthodes communes des séquences élémentaires (2/2) void push_back(const T& ); Ajout (recopie) de l'élément en fin void pop_back(); Suppression de l’élément en fin de séquence iterator insert(iterator, const T& = T()); Insertion d’un élément à l'emplacement spécifié par l'itérateur void insert(iterator position, iterator debut, iterator, fin) Insertion à la position spécifiée les éléments de [debut fin[ void swap(sequence <T>&back()) Echange des éléments de this avec ceux du conteneur argument void erase(iterator i); Suppression de l'élément pointé par l'itérateur i void erase(iterator debut, iterator fin); Supprime des éléments de [debut fin[

  11. 1.1. SEQUENCES ELEMENTAIRES Classe générique et instanciation • Définition de la classe générique vector • template <class T, class Alloc=alloc> • class vector {...}; • 2 paramètres formels génériques • T : type des éléments du vecteur • Alloc : type de la gestion mémoire (allocation/désallocation) • Remarque : Alloc a une valeur pardéfaut : alloc • Déclaration d’un vecteur : instanciation du générique • Pour déclarer un objet de type vector, on instancie la classe génériquevector en précisant (dans l’ordre et séparés par une virgule) les paramètres effectifs correspondants aux paramètres formels génériques • Exemple : pour déclarer un vecteur de flottants • vector <double> vi; //sans autre paramètre, //alloc (paramètre par défaut) est considéré • Notation SGI vector <T, Alloc=alloc> que nous noterons vector <T>

  12. 1.1. SEQUENCES ELEMENTAIRES - Conteneur VECTOR Instanciation, propriétés et méthodes spécifiques vector <T> v; Déclaration d’un vecteur v d’éléments de type T vector <T> v(n); Déclaration d’un vecteur v de n éléments de type T Extension de la structure classique de tableau(liste) Création et variation de la taille au cours de l’exécution Fonctions d’insertion et de suppression non optimisées (sauf en fin de vecteur) Méthodes spécifiques size-type capacity() const; Capacité actuelle du conteneur void reserve(size_type); Ajout de capacité T& operator [](size_type) ou T& at(size_type); Accès direct

  13. 1.1. SEQUENCES ELEMENTAIRES - Conteneur VECTOR Exemple #include <iostream> #include <vector> usingnamespace std; int main() { int tabEnt[] = {10, 15, 23, 67, 43, 98, 34, 77}; vector <int> vi; for (int i = 0; i < sizeof(tabEnt) / sizeof(int); i++) vi.push_back(tabEnt[i]); cout << "Taille : " << vi.size() << " – Vecteur : "; for (int i = 0; i < vi.size(); i++)cout << vi[i] << " "; } Résultat d’exécution Taille : 8 – Vecteur : 10 15 23 67 43 98 34 77

  14. 1.1. SEQUENCES ELEMENTAIRES - Conteneur DEQUE Instanciation, propriétés et méthodes spécifiques deque <T> d; Déclaration d’une deque d d’éléments de type T deque <T> d(n); Déclaration d’une deque d de n d’éléments de type T Fonctionnalités voisines de celles du conteneur vector + Insertion et suppression en début de séquence plus rapide - Accès direct plus lent Méthodes spécifiques void push_front(const T&) const; Insertion d’un élément en début de séquence void pop_front(); Suppression en début de séquence T& operator [](size_type); et T& at(size_type); Accès direct

  15. 1.1. SEQUENCES ELEMENTAIRES - Conteneur DEQUE Exemple #include <iostream> #include <deque> usingnamespace std; int main() { int tabEnt[] = {10, 15, 23, 67, 43, 98, 34, 77}; deque <int> di; for (int i = 0; i < sizeof(tabEnt) / sizeof(int); i++) di.push_front(tabEnt[i]); cout << "Taille : " << di.size() << " – Deque : "; for (int i = 0; i < di.size(); i++)cout << di[i] << " "; } Résultat d’exécution Taille : 8 – Deque : 77 34 98 43 67 23 15 10

  16. 1.1. SEQUENCES ELEMENTAIRES - Conteneur LIST Instanciation, propriétés et méthodes spécifiques (1/2) list <T> l; Déclaration d’une liste l d’éléments de type T list <T> l(n); Déclaration d’une liste l de n d’éléments de type T Spécialisation de la structure classique de liste + Fonctions rapides d’insertion et de suppression - Accès séquentiel fonctions rapides (tri, concaténation, …) Méthodes spécifiques void push_front(const T&) const; Insertion d’un élément en début de séquence void pop_front(); Suppression de l’élément en début de séquence void remove(const& T valeur); Suppression de tous les éléments égaux à valeur void remove_if(Predicate pred); Suppression de tous les éléments vérifiant pred

  17. 1.1. SEQUENCES ELEMENTAIRES - Conteneur LIST Méthodes spécifiques (2/2) void sort([Compare cmp]); Tri des éléments selon l'opérateur < ou le foncteur cmp void reverse([Compare cmp])); Inversion de l'ordre des éléments selon l'opérateur < ou le foncteur cmp void unique([Compare cmp]); Suppression sur une liste triée des éléments en double void merge(list<T> & x [, Compare cmp]); Fusion de la liste triée avec une autre liste x triée de même type, x est vidé. void splice(iterator i, list<T>& x); Déplacement de la liste x dans la liste this avant l’élément pointé par l’itérateur i void splice(iterator i, list<T>& x, iterator j); Déplacement de l’élément de x pointé par l’itérateur j dans la liste this avant l’élément pointé par l’itérateur i void splice(iterator i, list<T>& x, iterator debut, iterator fin); Déplacement de la séquence d’éléments [debut fin[ de x dans la liste this avant l’élément pointé par l’itérateur i

  18. V.begin() V.end() 12 3 25 7 39 27 1.1. SEQUENCES ELEMENTAIRES - Conteneur LIST Rôle des itérateurs • Variable qui repère la position d'un élément dans un conteneur • L’itérateur permet d’accéder/balayer les éléments d'un conteneur • A chaque conteneur son type d’itérateur • Quelque soit la classe conteneur : 2 méthodes membres • Début de la collection (position du premier élément) • Itérateur renvoyé par la méthode membre begin() • Fin de la collection (position de l'élément "juste après le dernier") • Itérateur renvoyé par la méthode membre end() • Accès à l’élémént repéré par l’itérateur It :*It • Exemple : • vector <int> V;

  19. 1.1. SEQUENCES ELEMENTAIRES - Conteneur LIST Exemple #include <iostream> #include <list> usingnamespace std; int main() { int tabEnt[] = {10, 15, 23, 67, 43, 98, 34, 77, 10}; list <int> li; for (int i = 0; i < sizeof(tabEnt) / sizeof(int); i++) li.insert(li.begin(), tabEnt[i]); li.sort(); li.unique(); cout << "Liste : "; for (list <int>::iterator i = li.begin(); i != li.end(); i++) cout << *i << " "; } Résultat d’exécution Liste : 10 15 23 34 43 67 77 98

  20. 1.2. ADAPTATEURS DE SEQUENCE Introduction Conteneurs implémentés à partir de séquences élémentaires stack Structure de données de pile - Last In First Out (LIFO) Insertions et retraits sur le haut de la pile queue Structure de données de file - First In First Out (FIFO) Insertions en fin et retraits en début priority_queue Structure de données de file avec priorité (fonction d'un prédicat) Après insertion d’élément, file maintenue triée par ordre croissant de priorité Insertions en fin et accès/retraits de l'élément de plus forte priorité Pas d’autres accès (direct ou séquentiel) Par conséquent, pas d’accès/balayage par itérateur

  21. 1.2. ADAPTATEURS DE SEQUENCE – Adaptateur STACK Instanciation, propriétés et méthodes spécifiques stack<T, Sequence=deque<T> > p; Déclaration d’une pile p d’éléments de type T Sequence : séquence élémentaire (générique) Implémentation d’une structure abstraite de pile Méthodes spécifiques bool empty(); true si la pile est vide, false sinon size_type size() const; Taille de la pile T& top() : Lecture du sommet de la pile (sans dépiler l’élément) void push(const T& ); Empiler l'élément void pop(); Dépiler un élément

  22. 1.2. ADAPTATEURS DE SEQUENCE – Adaptateur STACK Exemple #include <iostream> #include <vector> #include <stack> usingnamespace std; int main() { float tabFlt[] = {10.2, 15.3, 23.1, 67.2, 43.4, 98.8, 34.6}; stack <float, vector<float> > pf; for (int i = 0; i < sizeof(tabFlt) / sizeof(float); i++) pf.push(tabFlt[i]); while (pf.empty() == false) { cout << pf.top() << " "; pf.pop(); } } Résultat d’exécution 34.6 98.8 43.4 67.2 23.1 15.3 10.2

  23. 1.2. ADAPTATEURS DE SEQUENCE – Adaptateur STACK Exemple Pile implémentée par un vecteur stack <int, vector<int> > S; S.push(8); S.push(4); // assert(S.size() ==2 ); // assert(S.top() == 4); S.pop(); // assert(S.top() == 8); S.pop(); // assert(S.empty());

  24. 1.2. ADAPTATEUR DES SEQUENCES – Adaptateur QUEUE Instanciation, propriétés et méthodes spécifiques queue<T, Sequence=deque<T> > f; Déclaration d’une file f d’éléments de type T Sequence : séquence élémentaire (générique) Implémentation d’une structure abstraite de file Fonctions membres bool empty(); true si la file est vide, false sinon size_type size() const; Taille de la file T& front() : Lecture de la tête de la file (sans retirer l’élément) void push(const T& ); Ajout de l'élément en queue (sans retirer l’élément) void pop(); Suppression d’un élément en tête de file

  25. 1.2. ADAPTATEUR DES SEQUENCES – Adaptateur QUEUE Exemple #include <iostream> #include <list> #include <queue> usingnamespace std; int main() { char tabChr[] = {'p', 'a', 'r', 'i', 's'}; queue <char, list<char> > fa; for (int i = 0; i < sizeof(tabChr) / sizeof(char); i++) fa.push(tabChr[i]); while (fa.empty() == false) { cout << fa.front() << " "; fa.pop();} } Résultat d’exécution p a r i s

  26. 1.2. ADAPTATEUR DES SEQUENCES – Adaptateur QUEUE Exemple File implémentée par une deque queue <int> Q; Q.push(8); Q.push(2); // assert(Q.size() == 2); // assert(Q.back() == 2); // assert(Q.front() == 8); Q.pop(); // assert(Q.front() == 2); Q.pop(); // assert(Q.empty());

  27. 1.2. ADAPTATEUR DES SEQUENCES – Adaptateur PRIORITY_QUEUE Instanciation, propriétés et méthodes spécifiques priority_queue<T, Sequence=deque<T>, Compare=less<T> > fp; Déclaration d’une file à priorité fp d’éléments de type T Sequence : séquence élémentaire (générique) Compare : prédicat binaire générique (foncteur) de comparaison d’éléments Implémentation d’une structure abstraite de file à priorité Méthodes spécifiques bool empty(); true si la file est vide, false sinon size_type size() const; Taille de la file T& top() : Lecture de la tête de la file (élément prioritaire) void push(const T& ); Ajout de l'élément en queue void pop(); Suppression d’un élément en tête

  28. 1.2. ADAPTATEUR DES SEQUENCES – Adaptateur PRIORITY_QUEUE Opérateur de comparaison Compare : définition du critère de priorité à partir d’un prédicat binaire de comparaison bool Compare<T> (const T& arg1, const T& arg2); paramètre générique : T, le type des élémentsretournevrai si arg1 et arg2 sont ordonnés, faux sinon 6 foncteurs prédéfinis (pour les types natifs) en C++ redéfinissant les opérateurs relationnels : equal_to <T> retourne (arg1 == arg2) not_equal_to <T> retourne (arg1 != arg2) greater <T> retourne (arg1 > arg2) less <T> retourne (arg1 < arg2) greater_equal <T> retourne (arg1 >= arg2) less_equal <T> retourne (arg1 <= arg2) Pour un type utilisateur T :Nécessité de redéfinir l’opérateur relationnel correspondant au foncteur choisi

  29. 1.2. ADAPTATEUR DES SEQUENCES – Adaptateur PRIORITY_QUEUE Exemple #include <iostream> #include <deque> #include <queue> usingnamespace std; int main() { char tabChr[] = {'p', 'a', 'r', 'i', 's'}; priority_queue<char, deque<char>, less<char> > fp; for (int i = 0; i < sizeof(tabChr) / sizeof(char); i++) fp.push(tabChr[i]); while (fp.empty() == false) { cout << fp.top() << " "; fp.pop(); } } Résultat d’exécution s r p i a

  30. Valeurs Priorité décroissante Valeurs Priorité décroissante 1.2. ADAPTATEUR DES SEQUENCES – Adaptateur PRIORITY_QUEUE Exemple – T est un type prédéfini Foncteur less<int> - élément prioritaire, de plus forte priorité priority_queue <int> P; //ordre décroissant de priorité P.push(1); P.push(8); P.push(4); // assert(P.size()==3); // assert(P.top() == 8); P.pop(); // assert(P.top() == 4); P.pop(); // assert(P.top() == 1); P.pop(); // assert(P.empty()); Foncteur greater<int> - élément prioritaire, de plus faible priorité priority_queue <int, greater<int> > P; //ordre croissant //de priorité P.push(1); P.push(8); P.push(4); // assert(P.size()==3); // assert(P.top() == 1); P.pop(); // assert(P.top() == 4); P.pop(); // assert(P.top() == 8); P.pop(); // assert(P.empty());

  31. 1.2. ADAPTATEUR DES SEQUENCES – Adaptateur PRIORITY_QUEUE Exemple – T est un type utilisateur Exemple : Gestion de produits par priorité de marge bénéficiaireLe produit prioritaire dans la file est celui de plus forte marge class Produit { float pV_; // prix de vente float pR_; // prix de revient // Définitions du constructeur, des accesseurs,… }; priority_queue <Produit> P;// Gestion des produits par une // une file à priorité implémentée // par une deque et less L’opérateur   "<" doit être redéfini pour le type Produit bool operator<(const Produit& P1, const Produit& P2) { return (P1.getPV()-P1.getPR())<(P2.getPV()-P2.getPR()) }

More Related