Ceci est une ancienne révision du document !
Chapitre précédent | Sommaire principal | Chapitre suivant |
---|
Le chapitre precedent presentais chaque collection et ses specificites, mais sans entrer dans les details. Certines fonctionnalites etant commune a plusieurs collections, ces fonctionnalites ne vont pas etre decrites par collection, mais par categories de fonctionnalites. N'hesitez pas a consulter la documentation pour savoir si une collection en particulier permet d'utiliser une fonctionnalite ou non.
Certaines fonctionnalites ont deja etaient decrites dans les chapitres precedents, ce chapitre ne sera qu'un rappel dans ce cas.
Vous avez deja utilise a plusieurs reprises des collections dans les chapitres precedents. Vous avez par exemple vu qu'une collection pouvait etre comparee par egalite (std::equal
), etre triee (en utilisant la comparaison “plus petit que” std::less
) ou etre copiee (std::copy
).
En fait, les fonctionnalites proposees par les collections depdendent des fonctionnalites possibles des elements qu'elle contient. Par exemple, copier une collection signifie en fait copier les elements un par un. Pour copier une collection, il faut donc que les elements soient copiables.
#include <vector> #include <memory> int main() { using copiable_collection = std::vector<std::shared_ptr<int>>; copiable_collection cc1 {}; copiable_collection cc2 = cc1; using noncopiable_collection = std::vector<std::unique_ptr<int>>; noncopiable_collection uc1 {}; noncopiable_collection uc2 = uc1; }
(Ne vous inquietez pas pour std::shared_ptr
et std::unique_ptr
, vous verrez ces classes plus tard. Elles sont utilisees ici uniquement parce que la premiere est copiable et pas la seconde.)
Dans ce code, avec une classe copiable (std::shared_ptr
), la copie sera autorisee (cc2 = cc1
). Au contraire, avec une classe non copiable (std::unique_ptr
), essayer de copier de collection (uc2 = uc1
) produira une erreur de compilation.
/usr/local/include/c++/5.3.0/bits/unique_ptr.h:356:7: note: declared here unique_ptr(const unique_ptr&) = delete; ^
(Le message d'erreur ne dit pas explicitement que std::unique_ptr
n'est pas copiable, il indique qu'une fonction particuliere, le constructeur par copie, est supprimee. Les messsages d'erreur en C++ sont parfois difficile a comprendre, cela fait partie de l'apprentissage du C++ d'apprendre a les comprendre.)
N'oubliez pas que les fonctionnalites decrites dans ce chapitre dependent donc du type d'element que vous utiliserez dans une collection.
Toutes les collections de la bibliotheque standard sont constructibles par defaut (DefaultConstructible), c'est a dire sans aucun parametre ou de liste de valeurs.
std::vector<int> v {}; std::list<double> l {}; std::map<char, std::string> m {};
Pour rappel, il existe d'autres syntaxes possibles pour creer une variable par defaut, qui ne sont pas recommandees, mais que vous pouvez rencontrer dans un ancien code C++.
std::vector<int> v; // sans accolades
Autre rappel, il est classique de faire l'erreur d'utiliser des parentheses. Dependant, cela ne permet pas de creer une collection par defaut. (Cela permet en fait de declarer une fonction.)
std::vector<int> v; // erreur, ce code declare une fonction
Les collections sont egalement copiables (Copy) et deplacables (Move), par construction (Constructible) et assignation (Assignable).
Lorsqu'une collection est copiee dans une autre collection, cela implique que chaque element de la premiere collection va etre copie dans la seconde collection. Au final, les deux collections contiendront la meme liste d'elements.
Lorsqu'une collection est deplacee dans une autre collection (par exemple en utilisant la fonction std::move
, qui se traduit par “deplacer”), cela signifie que les elements sont retires de la premiere collection pour etre deplacer dans la seconde. Au final, la premiere collection sera vide et la seconde contiendra les elements qui se trouvaient precedement dans la premiere collection.
#include <iostream> #include <vector> int main() { std::vector<int> v1 { 1, 2, 3 }; std::vector<int> v2 = v1; // copie std::cout << v1.size() << ' ' << v2.size() << std::endl; std::vector<int> v3 = std::move(v1); // deplacement std::cout << v1.size() << ' ' << v3.size() << std::endl; }
affiche :
3 3 0 3
Apres la copie, les collections v1
et v2
contiennent tous les deux trois elements. Apres le deplacement, la collection v1
ne contient plus d'element, alors que v3
contient trois elements.
Les notions de copie et deplacement d'objets sont tres importantes en C++, en particulier pour la gestion de la duree de vie des objets. Cela sera approfondi dans un chapitre dans la suite de ce cours.
assignation
assign, paire d'iterateurs
std::vector<int> v { 1, 2, 3, 4 };
std::vector<int> v (5); std::vector<int> v (5, 123);
Attention entre v(5) et v{5}.
resize + reserve
Size, capacité, empty, shrink_to_fit. swap
Ajout et suppression d'éléments. L'idiome remove-erase. emplace vs push/insert
Complexité algo
Accès aux éléments (random access, front, back)
Autres fonctions membre (find, count, etc)
Itérateurs
allocator, data()
Chapitre précédent | Sommaire principal | Chapitre suivant |
---|