Последовательные контейнеры Qt.
Здравствуйте. В этой статье мы рассмотрим последовательные контейнеры Qt. К их числу относятся QVector<T>, QByteArray, QBitArray, QList<T>, QLinkedList<T>, QStack<T>, QQueue<T>, QStringList. Все эти контейнеры объединяет то, что элементы в них упорядочены и следуют друг за другом.
В таблице ниже приведены методы общие для всех последовательных контейнеров:
| Функция | Описание |
|---|---|
| + | Конкатенация контейнеров |
| += | Добавление в конец контейнера |
| << | Добавление элемента |
| at() | Операция индексирования с проверкой |
| back(), last() | Возвращают ссылку на последний элемент. Контейнер должен быть не пуст. |
| contains() | Вернет true, если контейнер содержит элемент аргумент функции |
| erase() | Удаляет элемент. Существует несколько вариаций функции. Удалять можно по целому индексу, по итератору и последовательность, обозначенную парой итераторов. |
| front(), first() | Возвращают ссылку на первый элемент. Контейнер должен быть не пуст. |
| indexOf() | Возвращает позицию первого вхождения элемента в последовательность |
| lastIndexOf() | Возвращает позицию последнего вхождения элемента в последовательность |
| mid() | Возвращает часть последовательности в виде последовательности заданной позицией и количеством элементов. |
| pop_back() | Удалить элемент с конца |
| pop_front() | Удалить элемент с начала |
| push_back (), append() | Добавляют элемент в конец последовательности |
| push_front(), prepend() | Добавляют элемент в начало последовательности |
QVector<T>. Вектор.
Вектор это некоторое обобщение массива. Сходство заключается в том, что он выделяет память для хранения своих элементов последовательно, но, разумеется, обеспечивает гораздо больше удобств, чем встроенный массив. Таких как динамическое изменение размера, резервирование памяти ну и еще кучу полезных методов ( смотрим мануал ) , не говоря уже о возможности применять к нему библиотечные алгоритмы.
Ну и как обычно сразу же приведу пример:
QVector<int> vint; // пустой вектор
QVector<int> vint2(10); // вектор размером 10 элементов со значениями по умолчанию
QVector<int> vint3(10,12); //вектор с 10 элементами, каждый из которых равен 12
QVector<int> vint4(vint4); //копия vint3
vint.push_back(12); //добавляем элемент в конец
qDebug()<<vint; // выводим наш вектор в консоль
В приведенном выше коде я затронул одну интересную особенность Qt. Для контейнеров перегружен оператор отладочного вывода, так, что код в последней строке выведет на консоль следующее:
QVector(12).
В таблице ниже приведены некоторые методы QVector:
| Метод | Описание |
|---|---|
| resize() | Динамически изменяет размер вектора |
| reserve() | Резервирует память для заданного количества элементов |
| data() | Возвращает содержимое вектора как указатель на первый элемент встроенного массива. |
| toStdVector() | Преобразует QVector к std::vector |
QByteArray.
QByteArray не является шаблоном и позволяет хранить элементы размером 1 байт. По интерфейсу он напоминает вектор. Он используется, например при работе с функциями сжатия Qt:
QByteArray data;
qCompress(data);
qUncompress(data);
QBitArray.
Класс не является шаблоном и представляет собой обобщение битового массива. Каждый элемент контейнера занимает ровно один бит. Как правило, используется для хранения последовательности bool. В таблице ниже приведены некоторые методы этого класса:
| Метод | Описание |
|---|---|
| testBit() | Вернет значение бита |
| setBit() | Установить бит по индексу |
| [] | Позволяет обращаться к отдельным битам |
Например:
QBitArray b(2);
b[0] = true;
b[1] = false;
QList<T>, QLinkedList<T>.
Списки это структуры использующие связанное распределение памяти, а не последовательное как QVector например. Это делает операцию индексации не эффективной, но зато изрядно оптимизирует вставку элементов, например в начало, для чего тому же вектору понадобится сдвигать все свои элементы, а списку нужно просто поменять местами пару указателей. Ну да ладно, мы тут Qt рассматриваем, а не сложные структуры данных, так, что не буду отвлекаться от темы. В таблице ниже приведены некоторые специфичные для списков операции:
| Метод | Описание |
|---|---|
| removeFirst() | Удаляет первый элемент списка |
| removeLast() | Удаляет последний элемент списка |
| toStdList() | Приводит список к виду std::list |
| swap() | Переставляет местами два элемента |
| move() | Меняет позицию элемента |
| takeFirst() | Возвращает первый элемент списка |
| takeLast() | Возвращает последний элемент списка |
Например:
QList<int> lint;
lint << 1 << 2 << 3;
qDebug()<<lint;
На консоли отобразится следующее:
QList(1,2,3)
Если предполагается, что в списке будет много элементов, или будет много вставок и удалений, рекомендуется использовать QLinkedList. Это двусвязный список. Он расходует несколько больше памяти, но делает операции вставки и удаления быстрее.
QStringList.
Это список строк. Интерфейс очень похож на интерфейс списка, но он оптимизирован для работы со строками.
QStringList slist;
slist << "string" << "string2";
Ну что ж, пора мне закругляться, обсуждение остальных контейнеров мы продолжим в следующих статьях.