Ответ 1
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 в качестве ссылки, то приведенная выше информация менее полезна.
An std::vector
- это массив, размер которого можно изменить. Все элементы хранятся рядом друг с другом, и вы можете быстро получить доступ к отдельным элементам. Недостатком является то, что вставки эффективны только с одного конца. Если вы помещаете что-то посередине или в начале, вам нужно скопировать другие объекты, чтобы освободить место. В примечаниях с большими охами вставка в конце - O (1), вставка где-либо еще - O (N), а произвольный доступ - O (1).
An std::deque
аналогичен, но объекты guarentee не хранятся рядом друг с другом и позволяют вставлять с обоих концов O (1). Это также требует выделения меньших фрагментов памяти за раз, что иногда может быть важным. Случайным доступом является O (1), а вставка в середине - O (N), такая же, как для a vector
. Местная местность хуже, чем std::vector
, но объекты, как правило, группируются, поэтому вы получаете некоторые преимущества.
An std::list
- связанный список. Это требует большого объема памяти из трех стандартных последовательных контейнеров, но предлагает быструю вставку в любом месте... если вы знаете заранее, где вам нужно вставить. Он не предлагает произвольный доступ к отдельным элементам, поэтому вам нужно итерации в O (N). Но как только там, фактическая вставка - O (1). Самое большое преимущество std::list
заключается в том, что вы можете быстро их объединить... если вы перемещаете весь диапазон значений в другой std::list
, вся операция O (1). Кроме того, гораздо сложнее сделать недействительными ссылки в списке, что иногда может быть важно.
Как правило, я предпочитаю std::deque
- std::vector
, если мне не нужно передавать данные в библиотеку, ожидающую необработанный массив. std::vector
гарантируется непрерывным, поэтому &v[0]
работает для этой цели. Я не помню, как в прошлый раз, когда я использовал std::list
, но это было почти наверняка, потому что мне нужен был более сильный guaretee относительно оставшихся ссылок.