Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ООПиП - задания к lab2.doc
Скачиваний:
11
Добавлен:
01.03.2016
Размер:
249.34 Кб
Скачать

Конструкция foreach

Если вы хотите перебрать все элементы контейнера по порядку, то можете использовать конструкцию Qt foreach. Данная конструкция - это дополнение Qt к языку C++, реализованное с помощью средств препроцессора.

Ее синтаксис: foreach (переменная, контейнер) оператор. В следующем примере показано использование конструкции foreach для перебора всех элементов контейнера QLinkedList<QString>:

QLinkedList<QString> list;

...

QString str;

foreach (str, list)

qDebug() << str;

Код с конструкцией foreach значительно короче, чем аналогичный код, который использует итераторы:

QLinkedList<QString> list;

...

QLinkedListIterator<QString> i(list);

while (i.hasNext())

qDebug() << i.next();

За исключением типа данных, содержащего запятую (например, QPair<int, int>), переменная, используемая для перебора элементов контейнера может быть определена внутри выражения foreach:

QLinkedList<QString> list;

...

foreach (const QString &str, list)

qDebug() << str;

И подобно любому циклу C++, вы можете заключить тело цикла foreach в фигурные скобки и использовать break для прерывания цикла:

QLinkedList<QString> list;

...

foreach (const QString &str, list) {

if (str.isEmpty())

break;

qDebug() << str;

}

При использовании с QMap и QHash, foreach предоставляет доступ к парам значений (key, value). Если вы хотите перебрать и ключи и значения, то можете использовать итераторы (которые быстрее) или написать код, подобный следующему:

QMap<QString, int> map;

...

foreach (const QString &str, map.keys())

qDebug() << str << ":" << map.value(str);

Для многосвязных карт:

QMultiMap<QString, int> map;

...

foreach (const QString &str, map.uniqueKeys()) {

foreach (int i, map.values(str))

qDebug() << str << ":" << i;

}

При входе в цикл foreach, Qt автоматически делает копию контейнера. Если вы измените контейнер во время выполнения цикла, то в цикле это не даст эффекта. (Если вы не изменяли контейнер, копирование все еще имеет место, но, благодаря неявному совместному использованию данных копирование контейнера осуществляется очень быстро.)

Поскольку для каждой итерации создаётся копия контейнера, то использование неконстантной ссылки на перменную не позволит изменять исходный контейнер. Изменения подействуют только на копию, что, вероятно, отличается от ваших ожиданий.

В дополнение к foreach, Qt также предоставляет псевдоключевое слово forever, для бесконечного цикла:

forever {

...

}

Если вас беспокоит засорение пространства имен, то вы можете отключить использование этих макросов, добавив в .pro-файл следующую строку:

CONFIG += no_keywords

Другие контейнероподобные классы

Qt включает три класса-шаблона, которые в некотором отношении напоминают контейнеры. Эти классы не предоставляют итераторов и не могут использоваться в конструкции foreach.

  • QVarLengthArray<T, Prealloc> предоставляет низкоуровневый массив переменной длины. Он может использоваться вместо QVector в тех местах, где скорость особенно важна.

  • QCache<Key, T> предоставляет кэш для хранения объектов некоторого типа T, ассоциированных с ключами типа Key.

  • QContiguousCache<T> предоставляет эффективный способ кэширования данных, доступ к которым обычно получают непрерывным способом.

  • QPair<T1, T2> хранит пары элементов.

Дополнительные нешаблонные типы, которые дополняют шаблонные контейнеры Qt, это - QBitArray, QByteArray, QString и QStringList.