QVector
ist meistens analog zu std::vector
, wie Sie aus dem Namen erraten können. QList
ist näher an boost::ptr_deque
, trotz der offensichtlichen Assoziation mit std::list
. Objekte werden nicht direkt gespeichert, sondern Zeiger auf sie. Sie profitieren von allen Vorteilen des schnellen Einfügens an beiden Enden, und bei Neuzuweisungen werden Zeiger anstelle von Kopierkonstruktoren gemischt, verlieren jedoch die räumliche Lokalität eines tatsächlichen std::deque
oder std::vector
und erhalten viele Heap-Zuweisungen. Es gibt einige Entscheidungen, um die Heap-Zuweisungen für kleine Objekte zu vermeiden und die räumliche Lokalität wiederzugewinnen, aber soweit ich weiß, gilt dies nur für Dinge, die kleiner als ein sind int
.
QLinkedList
ist analog zu std::list
und hat alle Nachteile. Im Allgemeinen sollte dies Ihre letzte Wahl für einen Container sein.
In der QT-Bibliothek wird die Verwendung von QList
Objekten stark bevorzugt. Wenn Sie sie also in Ihrem eigenen Code bevorzugen, können Sie manchmal unnötige Langeweile vermeiden. Die zusätzliche Heap-Verwendung und die zufällige Positionierung der tatsächlichen Daten können unter bestimmten Umständen theoretisch schaden, sind jedoch häufig nicht bemerkbar. Daher würde ich vorschlagen, QList
bis die Profilerstellung einen Wechsel zu a vorschlägt QVector
. Wenn Sie erwarten, dass eine zusammenhängende Zuordnung wichtig ist [lesen Sie: Sie arbeiten mit Code zusammen, der ein T[]
statt eines erwartet QList<T>
], kann dies auch ein Grund sein, sofort damit zu beginnen QVector
.
Wenn Sie allgemein nach Containern fragen und nur die QT-Dokumente als Referenz verwenden, sind die oben genannten Informationen weniger nützlich.
An std::vector
ist ein Array, dessen Größe Sie ändern können. Alle Elemente werden nebeneinander gespeichert, und Sie können schnell auf einzelne Elemente zugreifen. Der Nachteil ist, dass Einfügungen nur an einem Ende effizient sind. Wenn Sie etwas in die Mitte oder am Anfang stellen, müssen Sie die anderen Objekte kopieren, um Platz zu schaffen. In der Big-Oh-Notation ist die Einfügung am Ende O (1), die Einfügung an einer anderen Stelle O (N) und der Direktzugriff O (1).
An std::deque
ist ähnlich, garantiert jedoch nicht, dass Objekte nebeneinander gespeichert werden, und ermöglicht das Einfügen an beiden Enden als O (1). Es müssen auch kleinere Speicherblöcke gleichzeitig zugewiesen werden, was manchmal wichtig sein kann. Der Direktzugriff ist O (1) und die Einfügung in der Mitte ist O (N), wie bei a vector
. Die räumliche Lokalität ist schlechter als std::vector
, aber Objekte sind in der Regel gruppiert, sodass Sie einige Vorteile erzielen.
An std::list
ist eine verknüpfte Liste. Es erfordert den größten Speicheraufwand der drei sequentiellen Standardcontainer, bietet jedoch eine schnelle Einfügung überall ... vorausgesetzt, Sie wissen im Voraus, wo Sie einfügen müssen. Es bietet keinen zufälligen Zugriff auf einzelne Elemente, daher müssen Sie in O (N) iterieren. Dort angekommen ist die tatsächliche Einfügung jedoch O (1). Der größte Vorteil std::list
besteht darin, dass Sie sie schnell zusammenfügen können. Wenn Sie einen gesamten Wertebereich auf einen anderen verschieben std::list
, ist die gesamte Operation O (1). Es ist auch viel schwieriger, Verweise in der Liste ungültig zu machen, was manchmal wichtig sein kann.
Als allgemeine Regel gilt, ziehe ich std::deque
an std::vector
, wenn ich die Daten in eine Bibliothek übergeben müssen in der Lage sein , die ein rohes Array erwartet. std::vector
ist garantiert zusammenhängend, &v[0]
funktioniert also für diesen Zweck. Ich erinnere mich nicht an das letzte Mal, als ich ein verwendet habe std::list
, aber es war fast sicher, weil ich die stärkere Garantie dafür brauchte, dass Referenzen gültig bleiben.