Разработка графического интерфейса с помощью библиотеки Qt3 | ||
---|---|---|
Пред. | Глава 11. Контейнерные классы. | След. |
Словари предназначены для хранения произвольного количества элементов, в виде пар "ключ-значение". Причем к "ключам" предъявляется требование уникальности. Словари обладают широкими возможностями доступа к произвольным элементам и незначительными накладными расходами на операцию добавления нового элемента. Если в словарь вставляется новое значение по существующему ключу, то оно затирает старое значение в паре "ключ-значение".
Рисунок 11.3. Словарь экземпляров класса Film.
class Film
{
public:
Film(const QString &title = "", int duration = 0);
QString title() const { return myTitle; }
void setTitle(const QString &title) { myTitle = title; }
int duration() const { return myDuration; }
void setDuration(int minutes) { myDuration = minutes; }
private:
QString myTitle;
int myDuration;
};
Film::Film(const QString &title, int duration)
{
myTitle = title;
myDuration = duration;
}
В этой версии отсутствует числовой идентификатор фильма,
поскольку теперь он будет использоваться в качестве "ключа" в
словаре. Кроме того, здесь отсутствуют операторы сравнения -- словари
изначально упорядочивают элементы по ключу, но не по значению.Класс словаря в STL определен под именем std::map<K, T>, в файле заголовка <map>. Ниже приводится пример объявления словаря, с целыми значениями в качестве ключей и Film -- в качестве значения:
map<int, Film> films;
Эквивалент в Qt -- QMap<K, T>:
QMap<int, Film> films;
Наиболее естесственный способ заполнения словарей -- присваивать
значение по заданному ключу:
films[4812] = Film("A Hard Day's Night", 85);
films[5051] = Film("Seven Days to Noon", 94);
films[1301] = Film("Day of Wrath", 105);
films[9227] = Film("A Special Day", 110);
films[1817] = Film("Day for Night", 116);
Итератор словаря предоставляет возможность доступа к паре
"ключ-значение". Ключ извлекается с помощью (*it).first, а значение --
(*it).second:
map<int, Film>::const_iterator it = films.begin();
while (it != films.end()) {
cerr << (*it).first << ": "
<< (*it).second.title().ascii() << endl;
++it;
}
Большинство компиляторов допускают запись в виде it->first и it->second, но более переносимый вариант, все
таки: (*it).first и
(*it).second.Итераторы словарей в Qt несколько отличаются от итераторов словарей в STL. В Qt ключ можно получить с помощью it.key(), а значение -- it.data():
QMap<int, Film>::const_iterator it = films.begin();
while (it != films.end()) {
cerr << it.key() << ": " << it.data().title().ascii() < endl;
++it;
}
При обходе словаря в цикле, элементы словаря всегда упорядочены
по значению ключа.Для доступа к значениям словаря и их изменения может использоваться оператор "[ ]", однако, при попытке получить значение по несуществующему в словаре ключу, будет создан новый элемент словаря с заданным ключом и пустым значением. Чтобы избежать случайного создания пустых элементов, используйте функцию find(), чтобы получить искомый элемент:
map<int, Film>::const_iterator it = films.find(1817);
if (it != films.end())
cerr << "Found " << (*it).second.title().ascii() << endl;
Эта функция вернет итератор end(),
если ключ отсутствует в словаре.В примере выше, в качестве ключа использовались целые числа, однако, для этих целей могут использоваться и другие типы. Наиболее популярный -- QString, например:
map<QString, QString> actorToNationality;
actorToNationality["Doris Day"] = "American";
actorToNationality["Greta Garbo"] = "Swedish";
Если необходимо хранить несколько значений с одинаковыми ключами,
используйте multimap<K, T>. Если
необходимо хранить одни только ключи, используйте set<K> или multiset<K>. Qt не имеет классов, эквивалентных
приведенным.Класс QMap<K, T> имеет несколько дополнительных функций, особенно удобных при работе с небольшими наборами данных. Функции QMap<K, T>::keys() и QMap<K, T>::values() возвращают списки QValueList ключей и значений словаря.
Пред. | В начало | След. |
Списки. | На уровень выше | Контейнеры указателей. |