Qt container classIt provides platform-independent behavior and implicit data sharing technology. The so-called platform independence, that is, the Qt container class does not have different implementations because of different compilers. The so-called "implicit data sharing" can also be called "copy on write during write ", this technique allows passing value parameters in the container class without additional performance loss.
Directory [Hide]
- 1. Ordered container
- 1.1 QVector <T>
- 1.2 qinilist <T>
- 1.3 QList <T>
- 1.4 QStringList
- 1.5 QStack <T>
- 1.6 QQueue <T>
- 2 iterator
- 2.1 Java-style iterator
- 2.2 STL-style iterator
- 2.3 implicit sharing
- 2.4 foreach Loop
- 3. Associate containers
- 3.1 QMap
- 3.2 QHash <K, T>
- 4. See
|
Sequential container QVector <T>
QVector <T>, that is, vector. QVector <T> is an array-like container that stores data in the continuous memory area. Data at random locations and data insertion at the end have a high validity rate, while data insertion at the center and header is costly.
QVector provides the subscript [] operator.
Use the append () function to add data at the end, or use the <operator instead of the append () function.
The basic type and pointer in QVector are initialized to 0, while the default constructor is called for classes.
Qinilist <T>
Qinilist <T> is a linked list that connects all data using pointers. Data insertion and deletion are fast, but access to random position values is slow.
The [] operator is not provided. You can only use the append () function, <operator, or iterator to add data.
QList <T>
The most important advantages of qvector and qw.list are as follows:
Supports [] operators;
The insert/delete operation at the header or tail is very fast, and the insert/delete operation in the middle is very fast when the size is less than 1000.
Unless we need to add or delete elements in the middle of a large set, or all elements must be stored continuously in the memory, we should always use qlist <t>.
QStringList
A subclass of qlist <qstring>, which provides many special operations for qstring.
QStack <T>
Stack, with the push (), pop (), top () function.
QQueue <T>
Queue, with the enqueue (), dequeue (), head () functions.
Iterator
Qt supports Java-style and STL-style iterators. Java-style iterators are easier to use, the STL-style iterator can be used in combination with algorithms in QT and STL, making it more powerful.
Java-style iterator
Each sequence container class has two Java-style iterator types: Read-Only iterator and read/write iterator.
The read-only traversal tool has three types: qvectoriterator <t>, qinilistiterator <t>, and qlistiterator <t>;
There are also three types of read/write traversal devices: qmutablevectoriterator <t>, qmutablelinkedlistiterator <t>, and qmutablelistiterator <t>.
When using the Java-style iterator, the first thing to be clear is that the iterator does not directly point to the elements in the container, but to the positions before or after the elements. The iterator is initialized before it points to the first element in the container. If an element exists on the right of the iterator, The hasNext () function returns true; next () the function returns the element on the right of the iterator and moves the iterator to the right of an element. The hasPrevious () and previous () functions perform operations in the opposite direction.
The remove () function always deletes the last skipped element.
The setValue () function always performs an update operation on the last element that has been skipped.
The insert () function inserts a new element at the position currently pointed by the iterator, and points the iterator to the position of subsequent elements of the new element. For example:
QMutableListIterator <double> I (list); while (I. hasNext () {if (I. next () <0.0) // I. remove (); // Delete // I. setValue (value); // change // I. insert (value); // insert}
STL-style iterator
Each sequence Container class has two STL-style iterator types: Container <T >:: iterator and Container <T >:: const_iterator. The last one returns the read-only pointer type.
The begin () function returns an STL-style iterator pointing to the first element, for example, list [0], and end () the function returns the STL-style traversal tool pointing to the last element. when the container is empty, the results of begin () and end () are the same.
Generally, you can call isEmpty () to check whether the container is empty, instead of comparing the results of in () and end.
You can use the +,-, and * operators for iterator of STL-style, similar to pointer usage.
The returned values of some QT functions are the container class. If you need to use the STL-style iterator to traverse the returned values, you must save a copy of the returned values and traverse the copies, otherwise, the so-called "dangling iterator" may occur ".
For example:
QList<int> list = splitter->sizes(); QList<int>::const_iterator i = list.begin(); while (i != list.end()) { doSomething(*i); ++i; }
If you use the return value directly, it is like the following code:
// WRONG QList<int>::const_iterator i = splitter->sizes().begin(); while (i != splitter->sizes().end()) { doSomething(*i); ++i; }
Note: If you use a read-only iterator of Java-style, the replication is completed implicitly to ensure that the iterator is always traversed on the copy.
Implicit sharing
The beauty of the implicit sharing mechanism in QT is that it encourages programmers to use the concise method of passing values when returning objects, rather than referencing or pointer.
In contrast, STL encourages programmers to use non-const references to transmit vectors to avoid overhead of copying function return values.
All containers in QT use the implicit sharing mechanism. In addition, many other classes such as qbytearray, qbrush, qfont, qimage, qstring also uses this mechanism-this ensures that these classes are highly efficient in passing values, whether as a parameter or function return value.
If we only perform read operations, the data will not be copied. Only when the data to be copied needs to be written will the data be actually copied, because of this, implicit data sharing is also called "Copy at write time ". Implicit data sharing does not require any additional operations. It is automatically performed.
Using the at () rather than the [] operator to perform read-only operations on a vector or list under the implicit sharing mechanism provided by QT is a better choice. Similarly, try to use constbegin () and constend () to avoid unnecessary copy operations.
Foreach Loop
Qt provides a method that does not use the traversal tool for traversal: foreach loop. This is actually a macro, and the code is as follows:
QLinkedList<Movie> list; Movie movie; ... foreach (movie, list) { if (movie.title() == "Citizen Kane") { std::cout << "Found Citizen Kane" << std::endl; break; } }
In QT, a macro is used to implement a foreach loop. There are two parameters. The first is a single object and becomes a traversal object, which is equivalent to a pointer to the element type of the container, and the second is a container class. It clearly means that each time an element in the container is retrieved, it is assigned to the previous traversal element for operation.
Associated container
Containers generally store binary groups rather than a single object. Binary groups are generally expressed as <key-value>, that is, "key-value pairs ".
QMap
Qmap <K, T> is a key-value pair data structure. It is actually implemented using the Skip table skip-list and stored in ascending order by K.
You can use the insert () function of qmap <K, T> to insert data into qmap <K, T>.
The [] operator can be used in both insert and delete operations, and its subscript is K. To avoid unnecessary null values, we recommend that you use vlaue () instead of [] to obtain values from qmap.
In qmap <K, T>, K and t can be basic data types, such as int and double. They can be pointers, or classes with Default constructors, copy constructors, and value assignment operators. In addition, K must be overloaded because qmap <K, T> must be sorted in K ascending order.
Qmap <K, T> provides the keys () and values () functions to obtain the set of keys and values. Both sets use qlist as the return value.
Map is a single-value type, that is, if a new value is assigned to an existing key, the old value will be overwritten. If you want a key to index multiple values, you can use qmultimap <K, T>. This class allows one key to index multiple values, for example:
QMultiMap<int, QString> multiMap; multiMap.insert(1, "one"); multiMap.insert(1, "eins"); multiMap.insert(1, "uno"); QList<QString> vals = multiMap.values(1);
QHash <K, T>
Qhash <K, T> is a key-Value Pair stored in hashes. The interfaces provided are similar to those provided by qmap.
Qhash <K, T> is much faster than qmap <K, T>, and its storage is not sorted. For qhash <K, T>, the type of K must be overloaded with the = Operator and must be supported by the global function qhash (). This function is used to return the hash value of the key. Qt has implemented the qhash () function for int, pointer, qchar, qstring, and qbytearray.
QHash <K, T> automatically allocates an initial size for the hash, and changes the size of the hash when data is inserted or deleted. We can use the reserve () function to expand the hash, and use the squeeze () function to reduce the hash to the minimum size (the minimum size is actually the minimum space that can store the data ). In use, we can use the reserve () function to expand the data item to the expected maximum value, insert the data, and then use the squeeze () function to shrink the space.
QHash <K, T> is also a single value type, but you can use the insertMulti () function or use the QMultiHash <K, T> class to insert multiple values for a key. In addition to QHash <K, T>, Qt also provides QCache <K, T> to provide cache. QSet <K> is used to store only keys. These two classes share the same QHash <K, T> and have K type restrictions.