Viadeo Twitter Google Bookmarks ! Facebook Digg del.icio.us MySpace Yahoo MyWeb Blinklist Netvouz Reddit Simpy StumbleUpon Bookmarks Windows Live Favorites 
Logo Documentation Qt ·  Page d'accueil  ·  Toutes les classes  ·  Toutes les fonctions  ·  Vues d'ensemble  · 

The Tulip Container Classes

Qt 4 introduces a new set of containers that supersede both the old QCollection pointer-based containers and the newer QTL value-based containers.

General Overview

The Tulip containers are similar to Qt 3's QTL containers (QValueList, QValueVector, QMap), but have the following advantages:

  • The containers provide new iterators with a nicer, less error-prone syntax than STL, inspired by Java's iterators. (The STL-style iterators are still available as a lightweight, STL-compatible alternative.)
  • The containers have been optimized for minimal code expansion.
  • An empty container performs no memory allocation, and only requires the same space as a pointer.
  • Even though they are implicitly shared, they can safely be copied across different threads without formality. There's no need to use QDeepCopy.

Tulip provides the following sequential containers: QList, QLinkedList, QVector, QStack, and QQueue. For most applications, QList is the best type to use. Although it is implemented as an array-list, it provides very fast prepends and appends. If you really need a linked-list, use QLinkedList; if you want your items to occupy consecutive memory locations, use QVector. QStack and QQueue are convenience classes that provide LIFO and FIFO semantics.

Tulip also provides these associative containers: QMap, QMultiMap, QHash, QMultiHash, and QSet. The "Multi" containers conveniently support multiple values associated with a single key. The "Hash" containers provide faster lookup by using a hash function instead of a binary search on a sorted set.

The Tulip containers support the foreach keyword, a Qt-specific addition to the C++ language that is implemented using the standard C++ preprocessor. The syntax is:

 foreach (variable, container)
     statement;

Example:

 QList<QString> list;
 ...
 foreach (const QString &str, list)
     cout << str.ascii() << endl;

The iterator variable can also be defined outside the loop. For example:

 QString str;
 foreach (str, list)
     cout << str.ascii() << endl;

Just like standard for loops, foreach supports braces, break, continue, and nested loops. Qt makes a copy of the container when it enters the loop. If you modify the container as you are iterating, that won't affect the loop.

For details about the new containers, see the Container Classes and Generic Algorithms overview documents.

In addition to the new containers, considerable work has also gone into QByteArray and QString. The Qt 3 QCString class has been merged with QByteArray. The new QByteArray automatically provides a '\0' terminator after the last character. For example, the byte array of size 5 containing "abcde" has a null byte at position 5 (one past the end). This solves all the typical problems that occurred in Qt 3 with conversions between QByteArray and QCString.

To avoid crashes, QByteArray::data() never returns a null pointer. Furthermore, the distinction between null and empty strings has been watered down so that QByteArray() == QByteArray("") and QString() == QString("").

Examples

The first group of examples show how to use the new Java-style iterators. The main difference between the Java-style iterators and the STL-style iterators is that the Java-style ones point between items (or before the first item, or after the last item), whereas the STL ones point at an item (or past the last item). One advantage of the Java-style iterators is that iterating forward and backward are symmetric operations.

Traversing a container using a Java-style iterator:

 // forward                                  // backward
 QList<QString> list;                        QList<QString> list;
 ...                                         ...
 QListIterator<QString> i(list);             QListIterator<QString> i(list);
 while (i.hasNext())                         i.toBack();
     cout << i.next().ascii() << endl;       while (i.hasPrev())
                                                 cout << i.prev().ascii() << endl;

Modifying items using a Java-style iterator:

 // forward                                  // backward
 QMutableListIterator<int> i(list);          QMutableListIterator<int> i(list);
 while (i.hasNext())                         i.toBack();
     if (i.next() > 128)                     while (i.hasPrev())
         i.setValue(128);                        if (i.prev() > 128)
                                                     i.setValue(128);

Removing items using a Java-style iterator:

 // forward                                  // backward
 QMutableListIterator<int> i(list);          QMutableListIterator<int> i(list);
 while (i.hasNext())                         i.toBack();
     if (i.next() % 2 != 0)                  while (i.hasPrev())
         i.remove();                             if (i.prev() % 2 != 0)
                                                     i.remove();

Iterating over items with a particular value using STL-style vs. Java-style iterators:

 // STL-style                                // Java-style
 QMap<int, QWidget *>::const_iterator i;     QMapIterator<int, QWidget *> i(map);
 for (i = map.begin(); i != map.end(); ++i)  while (i.findNext(widget))
     if (i.value() == widget)                    cout << "Found widget " << widget
         cout << "Found widget " << widget            << " under key "
              << " under key "                        << i.key() << endl;
              << i.key() << endl;

Modifying and removing items using STL-style vs. Java-style iterators:

 // STL-style                                // Java-style
 QList<int>::iterator i = list.begin();      QMutableListIterator<int> i(list);
 while (i != list.end()) {                   while (i.hasNext()) {
     if (*i == 0) {                              int val = i.next();
         i = list.erase(i);                      if (val < 0)
     } else {                                        i.setValue(-val);
         if (*i < 0)                             else if (val == 0)
             *i = -*i;                               i.remove();
         ++i;                                }
     }
 }

The next group of examples show the API of the container classes themselves. The API is similar to the QTL classes of Qt 3, but is nicer in many respects.

Iterating over a QList using an index (which is fast even for large lists, because QList is implemented as an array-list):

 QList<double> list;
 ...
 for (int i = 0; i < list.size(); ++i) {
     if (list[i] < 0.0)
         list[i] = 0.0;
 }

Retrieving a value from a map, using a default value if the key doesn't exist:

 QMap<QString, int> map;
 ...
 map.value("TIMEOUT", 30);  // returns 30 if "TIMEOUT" isn't in the map

Getting all the values for a particular key in a QMultiMap or QMultiHash:

 QMultiMap<QString, int> map;
 ...
 QList<int> values = map.values("TIMEOUT");

Comparison with Qt 3

Tulip containers are value based. If you want to store a list where each item is a QWidget *, use QList<QWidget *>.

The new containers do not support auto-delete. In practice, we discovered that the only case where auto-delete proved worthwhile was when the data really should be stored as a value rather than as a pointer (e.g., QList<int> rather than QList<int *>). If you need to delete all the items in a container, use qDeleteAll().

If you use QValueList in Qt 3, you can replace it with either QList or QLinkedList in Qt 4. In most cases, QList is the best choice: It is typically faster, results in less code in your executable, and requires less memory. However, QLinkedList's iterators provide stronger guarantees, and only QLinkedList provides constant-time insertions in the middle, which can make a difference for lists with thousands of items.

If you use QValueVector or QMap in Qt 3, the corresponding Qt 4 classes (QVector, QMap) are very similar to use.

Publicité

Best Of

Actualités les plus lues

Semaine
Mois
Année
  1. « Quelque chose ne va vraiment pas avec les développeurs "modernes" », un développeur à "l'ancienne" critique la multiplication des bibliothèques 82
  2. Apercevoir la troisième dimension ou l'utilisation multithreadée d'OpenGL dans Qt, un article des Qt Quarterly traduit par Guillaume Belz 0
  3. Les développeurs ignorent-ils trop les failles découvertes dans leur code ? Prenez-vous en compte les remarques des autres ? 17
  4. BlackBerry 10 : premières images du prochain OS de RIM qui devrait intégrer des widgets et des tuiles inspirées de Windows Phone 0
  5. Quelles nouveautés de C++11 Visual C++ doit-il rapidement intégrer ? Donnez-nous votre avis 10
  6. Adieu qmake, bienvenue qbs : Qt Building Suite, un outil déclaratif et extensible pour la compilation de projets Qt 17
  7. 2017 : un quinquennat pour une nouvelle version du C++ ? Possible, selon Herb Sutter 6
Page suivante

Le Qt Labs au hasard

Logo

Quand il est juste de se tromper

Les Qt Labs sont les laboratoires des développeurs de Qt, où ils peuvent partager des impressions sur le framework, son utilisation, ce que pourrait être son futur. Lire l'article.

Communauté

Ressources

Liens utiles

Contact

  • Vous souhaitez rejoindre la rédaction ou proposer un tutoriel, une traduction, une question... ? Postez dans le forum Contribuez ou contactez-nous par MP ou par email (voir en bas de page).

Qt dans le magazine

Cette page est une traduction d'une page de la documentation de Qt, écrite par Nokia Corporation and/or its subsidiary(-ies). Les éventuels problèmes résultant d'une mauvaise traduction ne sont pas imputables à Nokia. Qt 4.7-snapshot
Copyright © 2012 Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon, vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. Cette page est déposée à la SACD.
Vous avez déniché une erreur ? Un bug ? Une redirection cassée ? Ou tout autre problème, quel qu'il soit ? Ou bien vous désirez participer à ce projet de traduction ? N'hésitez pas à nous contacter ou par MP !
 
 
 
 
Partenaires

Hébergement Web