Blame qtools/qtl.doc

Packit 1c1d7e
/****************************************************************************
Packit 1c1d7e
** 
Packit 1c1d7e
**
Packit 1c1d7e
** Qt template library classes documentation
Packit 1c1d7e
**
Packit 1c1d7e
** Copyright (C) 1992-2000 Trolltech AS.  All rights reserved.
Packit 1c1d7e
**
Packit 1c1d7e
** This file is part of the Qt GUI Toolkit.
Packit 1c1d7e
**
Packit 1c1d7e
** This file may be distributed under the terms of the Q Public License
Packit 1c1d7e
** as defined by Trolltech AS of Norway and appearing in the file
Packit 1c1d7e
** LICENSE.QPL included in the packaging of this file.
Packit 1c1d7e
**
Packit 1c1d7e
** This file may be distributed and/or modified under the terms of the
Packit 1c1d7e
** GNU General Public License version 2 as published by the Free Software
Packit 1c1d7e
** Foundation and appearing in the file LICENSE.GPL included in the
Packit 1c1d7e
** packaging of this file.
Packit 1c1d7e
**
Packit 1c1d7e
** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
Packit 1c1d7e
** licenses may use this file in accordance with the Qt Commercial License
Packit 1c1d7e
** Agreement provided with the Software.
Packit 1c1d7e
**
Packit 1c1d7e
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
Packit 1c1d7e
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
Packit 1c1d7e
**
Packit 1c1d7e
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
Packit 1c1d7e
**   information about Qt Commercial License Agreements.
Packit 1c1d7e
** See http://www.trolltech.com/qpl/ for QPL licensing information.
Packit 1c1d7e
** See http://www.trolltech.com/gpl/ for GPL licensing information.
Packit 1c1d7e
**
Packit 1c1d7e
** Contact info@trolltech.com if any conditions of this licensing are
Packit 1c1d7e
** not clear to you.
Packit 1c1d7e
**
Packit 1c1d7e
**********************************************************************/
Packit 1c1d7e
Packit 1c1d7e
/*!
Packit 1c1d7e
\page qtl.html
Packit 1c1d7e
Packit 1c1d7e
\title Qt Template library
Packit 1c1d7e
Packit 1c1d7e
Thq Qt Template Library is a set of templates within Qt dealing with
Packit 1c1d7e
containers of objects.  It provides a list of objects, a stack of
Packit 1c1d7e
objects, a map (or dictionary) from one type to another, and
Packit 1c1d7e
associated iterators and algorithms.
Packit 1c1d7e
Packit 1c1d7e
Qt also contains similar classes that deal with pointers to objects;
Packit 1c1d7e
\l QValueList vs. \l QList, etc.  Compared to the pointer-based
Packit 1c1d7e
templates, the QTL offers easy copying of the container, real support
Packit 1c1d7e
for classes that e.g. require constructors, expand to much more object
Packit 1c1d7e
code, can often be a bit faster, require that the objects stored can
Packit 1c1d7e
be copied, and finally, have a worse record of compiler problems.
Packit 1c1d7e
Packit 1c1d7e
Compared to the STL, the QTL contains only the most important features
Packit 1c1d7e
of the STL, has more regular function naming, has no platform
Packit 1c1d7e
differences, is often a little slower and often expands to less object
Packit 1c1d7e
code.
Packit 1c1d7e
Packit 1c1d7e
Packit 1c1d7e
If you can not make copies of the objects you want to store you are
Packit 1c1d7e
better off with QCollection and friends. They were designed to handle
Packit 1c1d7e
exactly that kind of pointer semantics. This applies for example to
Packit 1c1d7e
all classes derived from \l QObject. A QObject does not have a copy
Packit 1c1d7e
constructor, so using it as value is impossible. You may choose be
Packit 1c1d7e
store pointers to QObjects in a QValueList, but using QList directly
Packit 1c1d7e
seems to be the better choice for this kind of application
Packit 1c1d7e
domain. QList, like all other QCollection based containers, provides
Packit 1c1d7e
far more sanity checking than a speed-optimized value
Packit 1c1d7e
based container.
Packit 1c1d7e
Packit 1c1d7e
If you have objects that implement value semantics, use the Qt
Packit 1c1d7e
template library.  Value semantics require at least
Packit 1c1d7e
    Packit 1c1d7e
  • a copy constructor,
  • Packit 1c1d7e
  • an assignment operator and
  • Packit 1c1d7e
  • a default constructor, i.e. a constructor that does not take
  • Packit 1c1d7e
    any arguments.
    Packit 1c1d7e
    Packit 1c1d7e
    Note that a fast copy constructor is absolutely crucial for a good
    Packit 1c1d7e
    overall performance of the container, since many copy operations are
    Packit 1c1d7e
    going to happen.
    Packit 1c1d7e
    Packit 1c1d7e
    Examples for value based classes are QRect, QPoint, QSize and all
    Packit 1c1d7e
    simple C++ types like int, bool or double.
    Packit 1c1d7e
    Packit 1c1d7e
    The Qt template library is designed for speed. Especially iterators
    Packit 1c1d7e
    are extremely fast. On the drawback side, less error checking is done
    Packit 1c1d7e
    than in the QCollection based containers. A template library container
    Packit 1c1d7e
    for example does not track associated iterators. This makes certain
    Packit 1c1d7e
    validity checks, like on removing items, impossible to perform
    Packit 1c1d7e
    automatically.
    Packit 1c1d7e
    Packit 1c1d7e

    Iterators

    Packit 1c1d7e
    Packit 1c1d7e
    The Qt template library deals with value objects, not with pointers.
    Packit 1c1d7e
    For that reason, there is no other way of iterating over containers
    Packit 1c1d7e
    than using iterators. This is no disadvantage as the size of an
    Packit 1c1d7e
    iterator matches the size of a normal pointer - 32 or 64 bits
    Packit 1c1d7e
    depending on your CPU architecture.
    Packit 1c1d7e
    Packit 1c1d7e
    To iterate over a container, use a loop like this:
    Packit 1c1d7e
    Packit 1c1d7e
    \code
    Packit 1c1d7e
    	typedef QValueList<int> List;
    Packit 1c1d7e
    	List l;
    Packit 1c1d7e
    	for( List::Iterator it = l.begin(); it != l.end(); ++it )
    Packit 1c1d7e
    		printf("Number is %i\n",*it);
    Packit 1c1d7e
    \endcode
    Packit 1c1d7e
    Packit 1c1d7e
    begin() returns the iterator pointing at the first element, while
    Packit 1c1d7e
    end() returns an iterator that points \e after the last
    Packit 1c1d7e
    element. end() marks an invalid position, it can never be
    Packit 1c1d7e
    dereferenced. It's the break condition in any iteration, may it be
    Packit 1c1d7e
    from begin() or fromLast(). For maximum speed, use increment or
    Packit 1c1d7e
    decrement iterators with the prefix operator (++it, --it) instead of the the
    Packit 1c1d7e
    postfix one (it++, it--), since the former is slightly faster.
    Packit 1c1d7e
    Packit 1c1d7e
    The same concept applies to the other container classes:
    Packit 1c1d7e
    Packit 1c1d7e
    \code
    Packit 1c1d7e
    	typedef QMap<QString,QString> Map;
    Packit 1c1d7e
    	Map map;
    Packit 1c1d7e
    	for( Map::Iterator it = map.begin(); it != map.end(); ++it )
    Packit 1c1d7e
    		printf("Key=%s Data=%s\n", it.key().ascii(), it.data().ascii() );
    Packit 1c1d7e
    Packit 1c1d7e
    	typedef QArray<int> Array;
    Packit 1c1d7e
    	Array array;
    Packit 1c1d7e
    	for( Array::Iterator it = array.begin(); it != array.end(); ++it )
    Packit 1c1d7e
    		printf("Data=%i\n", *it );
    Packit 1c1d7e
    \endcode
    Packit 1c1d7e
    Packit 1c1d7e
    There are two kind of iterators, the volatile iterator shown in the
    Packit 1c1d7e
    examples above and a version that returns a const reference to its
    Packit 1c1d7e
    current object, the ConstIterator. Const iterators are required
    Packit 1c1d7e
    whenever the container itself is const, such as a member variable
    Packit 1c1d7e
    inside a const function. Assigning a ConstIterator to a normal
    Packit 1c1d7e
    Iterator is not allowed as it would violate const semantics.
    Packit 1c1d7e
    Packit 1c1d7e

    Algorithms

    Packit 1c1d7e
    Packit 1c1d7e
    The template library defines a number of algorithms that operate on
    Packit 1c1d7e
    its containers: qHeapSort(), qBubbleSort(), qSwap() and
    Packit 1c1d7e
    qCopy(). These algorithms are implemented as template functions.
    Packit 1c1d7e
    Packit 1c1d7e
    qHeapSort() and qBubbleSort() provide the well known sorting
    Packit 1c1d7e
    algorithms. You can use them like this:
    Packit 1c1d7e
    Packit 1c1d7e
    \code
    Packit 1c1d7e
    	typedef QValueList<int> List;
    Packit 1c1d7e
    	List l;
    Packit 1c1d7e
    	l << 42 << 100 << 1234 << 12 << 8;
    Packit 1c1d7e
    	qHeapSort( l );
    Packit 1c1d7e
    	
    Packit 1c1d7e
    	List l2;
    Packit 1c1d7e
    	l2 << 42 << 100 << 1234 << 12 << 8;
    Packit 1c1d7e
    	List::Iterator b = l2.find( 100 );
    Packit 1c1d7e
    	List::Iterator e = l2.find( 8 );
    Packit 1c1d7e
    	qHeapSort( b, e );
    Packit 1c1d7e
    Packit 1c1d7e
    	double arr[] = { 3.2, 5.6, 8.9 };
    Packit 1c1d7e
    	qHeapSort( arr, arr + 3 );
    Packit 1c1d7e
    \endcode
    Packit 1c1d7e
    Packit 1c1d7e
    The first example sorts the entire list. The second one sorts all
    Packit 1c1d7e
    elements enclosed in the two iterators, namely 100, 1234 and 12.  The
    Packit 1c1d7e
    third example shows that iterators act like pointers and can be
    Packit 1c1d7e
    treated as such.
    Packit 1c1d7e
    Packit 1c1d7e
    Naturally, the sorting templates won't work with const iterators.
    Packit 1c1d7e
    Packit 1c1d7e
    Another utility is qSwap(). It exchanges the values of two variables:
    Packit 1c1d7e
    Packit 1c1d7e
    \code
    Packit 1c1d7e
    	QString second( "Einstein" );
    Packit 1c1d7e
    	QString name( "Albert" );
    Packit 1c1d7e
    	qSwap( second, name );
    Packit 1c1d7e
    \endcode
    Packit 1c1d7e
    Packit 1c1d7e
    Another template function is qCopy(). It copies a container or a slice
    Packit 1c1d7e
    of it to an OutputIterator, in this case a QTextOStreamIterator:
    Packit 1c1d7e
    Packit 1c1d7e
    \code
    Packit 1c1d7e
    	typedef QValueList<int> List;
    Packit 1c1d7e
    	List l;
    Packit 1c1d7e
    	l << 100 << 200 << 300;
    Packit 1c1d7e
    	QTextOStream str( stdout );
    Packit 1c1d7e
    	qCopy( l, QTextOStreamIterator( str ) );
    Packit 1c1d7e
    \endcode
    Packit 1c1d7e
    Packit 1c1d7e
    In addition, you can use any Qt template library iterator as the
    Packit 1c1d7e
    OutputIterator. Just make sure that the right hand of the iterator has
    Packit 1c1d7e
    as many elements present as you want to insert. The following example
    Packit 1c1d7e
    illustrates this:
    Packit 1c1d7e
    Packit 1c1d7e
    \code
    Packit 1c1d7e
    	QStringList l1, l2;
    Packit 1c1d7e
    	l1 << "Weis" << "Ettrich" << "Arnt" << "Sue";
    Packit 1c1d7e
    	l2 << "Torben" << "Matthias";
    Packit 1c1d7e
    	qCopy( l2, l1.begin();
    Packit 1c1d7e
    \endcode
    Packit 1c1d7e
    Packit 1c1d7e
    At the end of this code fragment, the List l1 contains "Torben",
    Packit 1c1d7e
    "Matthias", "Arnt" and "Sue", with the prior contents being
    Packit 1c1d7e
    overwritten. Another flavor of qCopy() takes three arguments to make
    Packit 1c1d7e
    it possible to copy a slice of a container:
    Packit 1c1d7e
    Packit 1c1d7e
    \code
    Packit 1c1d7e
    	typedef QValueList<int> List;
    Packit 1c1d7e
    	List l;
    Packit 1c1d7e
    	l << 42 << 100 << 1234 << 12 << 8;
    Packit 1c1d7e
    	List::Iterator b = l.find( 100 );
    Packit 1c1d7e
    	List::Iterator e = l.find( 8 );
    Packit 1c1d7e
    	QTextOStream str( stdout );
    Packit 1c1d7e
    	qCopy( b, e, QTextOStreamIterator( str ) );
    Packit 1c1d7e
    \endcode
    Packit 1c1d7e
    Packit 1c1d7e
    If you write new algorithms, consider writing them as template
    Packit 1c1d7e
    functions in order to make them usable with as many containers
    Packit 1c1d7e
    possible.  In the above example, you could just as easily print out a
    Packit 1c1d7e
    standard C++ array with qCopy():
    Packit 1c1d7e
    Packit 1c1d7e
    \code
    Packit 1c1d7e
    	int arr[] = { 100, 200, 300 };
    Packit 1c1d7e
    	QTextOStream str( stdout );
    Packit 1c1d7e
    	qCopy( arr, arr + 3, QTextOStreamIterator( str ) );	
    Packit 1c1d7e
    \endcode
    Packit 1c1d7e
    Packit 1c1d7e
    Packit 1c1d7e

    Streaming

    Packit 1c1d7e
    Packit 1c1d7e
    All mentioned containers can be serialized with the respective
    Packit 1c1d7e
    streaming operators. Here is an example.
    Packit 1c1d7e
    Packit 1c1d7e
    \code
    Packit 1c1d7e
    	QDataStream str(...);
    Packit 1c1d7e
    	QValueList<QRect> l;
    Packit 1c1d7e
    	// ... fill the list here
    Packit 1c1d7e
    	str << l;
    Packit 1c1d7e
    \endcode
    Packit 1c1d7e
    Packit 1c1d7e
    The container can be read in again with:
    Packit 1c1d7e
    Packit 1c1d7e
    \code
    Packit 1c1d7e
    	QValueList<QRect> l;
    Packit 1c1d7e
    	str >> l;
    Packit 1c1d7e
    \endcode
    Packit 1c1d7e
    Packit 1c1d7e
    The same applies to QStringList, QValueStack and QMap.
    Packit 1c1d7e
    Packit 1c1d7e
    */