La librairie standard C++ est composée:
Comme en Java, une bonne maîtrise du langage C++, c'est aussi une bonne maîtrise de la librairie standard.
Sa force est
Un conteneur est un ensemble structuré de données:
Consultez aussi http://www.cplusplus.com/.
Tous les conteneurs sont paramétrables par le type d'éléments à contenir (via le mécanisme template) et ont un constructeur par défaut:
#include<vector>
#include<list>
#include<set>
#include<map>
...
std::vector<double> v1;
std::vector<std::string> v2;
std::list<int> l;
std::set<std::string> s;
std::map<std::string, int> m;
Les conteneurs ainsi créés sont vides.
Les conteneurs qui satisfont le concept de Sequence ont une méthode insert() qui prend en paramètre la valeur à insérer.
s.insert("toto");
Les conteneurs qui satisfont en plus le concept BackInsertionSequence, comme std::vector ou std::list, ont une méthode push_back() pour ajouter à la fin du conteneur.
v1.push_back(2.0);
Les std::map sont des ensembles de paires (clé-valeur). Les paires sont modélisés par la classe std::pair.
std::pair<std::string, int> p("janvier", 31);
Attention, dans std::map, ce sont des paires qui sont stockées; on insère donc des paires:
m.insert( p );
Un iterateur est un objet léger donnant un moyen de parcourir, lire et/ou écrire les données d'un conteneur.
Ce sont une généralisation des pointeurs. En tant que tels, si it est un iterateur, on peut faire, entre autres opérations, it++ pour atteindre la donnée suivante et *it pour obtenir la donnée pointée.
Tous les conteneurs de la STL ont les types internes suivants
et fournissent des iterateurs par les méthodes suivantes
En général, on ne construit pas un iterateur de zéro, on en demande aux conteneurs.
Avec un itérateur, le parcours de tous les éléments d'un conteneur ressemble à ceci:
for (Conteneur::const_iterator it = leConteneur.begin();
it != leConteneur.end(); it++)
{
*it = 0; //initialisation a zero
}
On imite ainsi le code C, basé sur un pointeur:
int tab[N];
for (int* ptr = tab; ptr != (tab + N); ptr++)
{
*ptr = 0;
}
De nombreux conteneurs supportent un parcours de leurs éléments dans les deux sens. Il suffit d'opter pour les bons itérateurs:
for (Conteneur::const_reverse_iterator it = leConteneur.rbegin();
it != leConteneur.rend(); it++)
{
...
}
Un range est un intervalle de données d'un conteneur implicitement décrit par une paire (ordonnée) d'itérateurs.
Par exemple, leConteneur.begin() et leConteneur.end() décrivent un range correspondant à l'ensemble des données du conteneur.
Pour une paire d'itérateurs (itb, ite), on suppose que:
Les algorithmes sont des fonctions dont les paramètres d'entrées sont des itérateurs sur un ou deux conteneurs (plus, pour certains un foncteur agissant sur les données) .
Cette interface sous forme de fonctions
Sont disponibles après #include<algorithm>:
Consultez la liste des algorithmes
Dans testVecteur.cpp:
Un foncteur est la généralisation d'une fonction. C'est un objet possédant l'opérateur (), qui admet le plus souvent aucun, un ou deux paramètres et retourne une valeur.
NB. Un predicat est un foncteur qui retourne une valeur de type bool.
Le foncteur se distingue d'une fonction en ce qu'il peut, comme tout objet, avoir un état.
Pour créer un foncteur, l'étape cruciale consiste à surcharger l'opérateur () (la méthode s'appelle operator(), d'où les doubles parenthèses):
#include<cstdlib> //pour std::rand
class GenerateurAleatoire {
public:
int operator()() {
return std::rand()%100;
}
};
Après avoir instancier votre foncteur, vous pouvez l'utiliser comme une fonction:
MonGenerateurAleatoire g;
std::cout << g() << std::endl; //entre 0 et 99
Dans cet example, on peut aussi bien utiliser une fonction:
int g() {
return std::rand()%100;
}
...
std::cout << g() << std::endl; //entre 0 et 99
Mais, un foncteur est adaptable, sans modifier la liste des paramètres de l'opérateur ():
#include<cstdlib> //pour std::rand
class GenerateurAleatoire {
public:
int monMax;
GenerateurAleatoire(int max): monMax(max) {}
int operator()() {
return std::rand()%monMax; //entre 0 et monMax-1
}
};
La STL est composé de:
Elle est générique, conteneurs et algorithmes sont orthogonaux.
Elle est compatible avec le C, notamment grâce à la surcharge d'opérateurs, qui permet d'écrire des généralisations des pointeurs (itérateurs) et des fonctions (foncteurs).