QVector
est en grande partie analogue à std::vector
comme vous pouvez le deviner d'après son nom. QList
est plus proche de boost::ptr_deque
malgré l'association apparente avec std::list
. Il ne stocke pas directement les objets, mais plutôt des pointeurs vers eux. Vous bénéficiez de tous les avantages des insertions rapides aux deux extrémités, et les réallocations impliquent le brassage des pointeurs au lieu des constructeurs de copie, mais vous perdez la localité spatiale d'un objet réel. std::deque
o std::vector
et gagner beaucoup d'allocations de tas. Il y a une certaine prise de décision pour éviter les allocations de tas pour les petits objets, regagnant la localité spatiale, mais d'après ce que j'ai compris, cela ne s'applique qu'aux choses plus petites qu'un an. int
.
QLinkedList
est analogue à std::list
et en a tous les inconvénients. D'une manière générale, ce devrait être votre dernier choix de conteneur.
La bibliothèque QT favorise fortement l'utilisation de la fonction QList
Par conséquent, les privilégier dans votre propre code peut parfois vous éviter des ennuis inutiles. L'utilisation supplémentaire du tas et le positionnement aléatoire des données réelles peuvent théoriquement nuire dans certaines circonstances, mais sont souvent imperceptibles. Je suggère donc d'utiliser QList
jusqu'à ce que le profilage suggère de passer à un QVector
. Si vous pensez que l'allocation contiguë est importante [lire : vous vous interfacez avec du code qui s'attend à une allocation contiguë], il est préférable d'utiliser une allocation contiguë. T[]
au lieu d'un QList<T>
] cela peut également être une raison de commencer par QVector
dès le départ.
Si vous posez des questions sur les conteneurs en général, et que vous avez juste utilisé les documents QT comme référence, alors les informations ci-dessus sont moins utiles.
Un site std::vector
est un tableau que vous pouvez redimensionner. Tous les éléments sont stockés les uns à côté des autres, et vous pouvez accéder rapidement aux éléments individuels. L'inconvénient est que les insertions ne sont efficaces qu'à une extrémité. Si vous placez un élément au milieu ou au début, vous devez copier les autres objets pour faire de la place. En notation big-oh, l'insertion à la fin est O(1), l'insertion partout ailleurs est O(N), et l'accès aléatoire est O(1).
Un site std::deque
est similaire, mais ne garantit pas que les objets sont stockés les uns à côté des autres, et permet à l'insertion aux deux extrémités d'être O(1). Elle nécessite également l'allocation de plus petits morceaux de mémoire à la fois, ce qui peut parfois être important. L'accès aléatoire est de O(1) et l'insertion au milieu est de O(N), comme dans le cas d'un vector
. La localisation spatiale est pire que std::vector
mais les objets ont tendance à être regroupés, ce qui présente certains avantages.
Un site std::list
est une liste chaînée. Parmi les trois conteneurs séquentiels standard, c'est celui qui nécessite le plus de mémoire, mais il permet une insertion rapide partout... à condition que vous sachiez à l'avance où vous devez insérer. Elle n'offre pas d'accès aléatoire aux éléments individuels, il faut donc itérer en O(N). Mais une fois là, l'insertion réelle est O(1). Le plus grand avantage de std::list
c'est que vous pouvez les assembler rapidement... si vous déplacez une gamme entière de valeurs vers un autre endroit... std::list
l'opération entière est O(1). Il est également beaucoup plus difficile d'invalider les références dans la liste, ce qui peut parfois être important.
En règle générale, je préfère std::deque
a std::vector
sauf si je dois être capable de passer les données à une bibliothèque qui attend un tableau brut. std::vector
est garanti contigu, donc &v[0]
travaille à cette fin. Je ne me souviens pas de la dernière fois où j'ai utilisé un std::list
mais c'était presque certainement parce que j'avais besoin d'une garantie plus forte sur la validité des références.