QVector
в основном аналогичен std::vector
, как можно догадаться из названия.QList
ближе к boost::ptr_deque
, несмотря на очевидную связь с std::list
.Он не хранит объекты напрямую, а хранит указатели на них.Вы получаете все преимущества быстрых вставок на обоих концах, а перераспределения включают в себя перетасовывание указателей вместо конструкторов копирования, но теряют пространственную локальность фактических std::deque
или std::vector
и получают много выделений кучи.У него есть какое-то решение, чтобы избежать выделения кучи для небольших объектов, восстановления пространственного местоположения, но, насколько я понимаю, это относится только к вещам, меньшим чем int
.
QLinkedList
аналогично std::list
, и имеет все недостатки этого.Вообще говоря, это должен быть ваш последний выбор контейнера.
Библиотека QT сильно поощряет использование QList
объектов, поэтому использование их в вашем собственном коде иногда может избежать ненужной скуки.Использование лишней кучи и случайное позиционирование фактических данных могут теоретически повредить в некоторых обстоятельствах, но зачастую это незаметно.Поэтому я бы предложил использовать QList
, пока профилирование не изменится на QVector
.Если вы ожидаете, что непрерывное выделение будет важным [читай: вы взаимодействуете с кодом, который ожидает T[]
вместо QList<T>
], что также может быть причиной для запуска с QVector
сразу же.
Если вы спрашиваете о контейнерах в целом и просто используете документы QT в качестве ссылки, то приведенная выше информация менее полезна.
std::vector
- это массив, размер которого можно изменить,Все элементы хранятся рядом друг с другом, и вы можете быстро получить доступ к отдельным элементам.Недостатком является то, что вставки эффективны только на одном конце.Если вы помещаете что-то в середину или в начале, вам нужно скопировать другие объекты, чтобы освободить место.В биг-ой нотации вставка в конце - это O (1), вставка в любом другом месте - O (N), а произвольный доступ - это O (1).
std::deque
аналогичен, но неГарантированные объекты хранятся рядом друг с другом и позволяют вставлять на обоих концах O (1).Это также требует, чтобы меньшие порции памяти были выделены за один раз, что иногда может быть важно.Произвольный доступ - O (1), а вставка в середине - O (N), такая же, как для vector
.Пространственная локальность хуже, чем std::vector
, но объекты имеют тенденцию к кластеризации, поэтому вы получаете некоторые преимущества.
std::list
- это связанный список.Он требует больше всего памяти из трех стандартных последовательных контейнеров, но предлагает быструю вставку в любое место ... при условии, что вы заранее знаете, куда нужно вставить.Он не предлагает произвольный доступ к отдельным элементам, поэтому вы должны выполнить итерацию в O (N).Но когда-то там, фактическая вставка O (1).Самым большим преимуществом std::list
является то, что вы можете быстро соединить их вместе ... если вы переместите весь диапазон значений в другое std::list
, вся операция будет O (1).Также намного труднее сделать недействительными ссылки в списке, что иногда может быть важно.
Как правило, я предпочитаю std::deque
std::vector
, если только мне не нужна возможность передавать данные вбиблиотека, которая ожидает необработанный массив.std::vector
гарантированно смежный, поэтому &v[0]
работает для этой цели.Я не помню, когда в последний раз я использовал std::list
, но это было почти наверняка, потому что мне нужна была более надежная гарантия того, что ссылки остаются в силе.