Symbian and Qt both provide an extensive set of array types for purposes such as containers, lists and hash maps. In some cases conversion can be avoided but in other cases the conversion is only possible using item-by-item iteration.
Symbian C++ provides a large number
of array classes, which should be used in preference to standard C/C++
arrays because of the protection they provide against memory overruns
etc. The arrays behave much like standard C++ arrays (stl::vector<>
); they are indexed by an integer, elements can be of any type (or
pointer to a type), the array does its internal reallocation when
adding or deleting.
The topic Arrays And Lists Overview gives an overview of the different array classes. There are four main categories:
CArrayX (CArrayFixFlat, CArrayVarFlat, CArrayPakFlat,
CArrayPtrFlat, CArrayFixSeg, CArrayVarSeg, CArrayPtrSeg
)
RArrays (RArray, RPointerArray
)
Fixed Array (TFixedArray
)
Descriptor Arrays (CDesC16ArrayFlat, CDesC8ArraySeg,
CDesC8ArrayFlat, CDesC8ArraySeg, CPtrC8Array, CPtrC16Array
)
The array naming convention uses Fix where the elements
of the array all have the same length and are copied directly into
the array buffer (for example, TPoint
, TRect
) and Var where the elements of the array are
pointers to objects of variable lengths contained elsewhere on the
heap (such asHBufC* or TAny*). Pak (for ‘packed’ array) is used where the elements
of the array are of variable length but are copied into the array
buffer with each preceded by its length (for example, T
class objects of variable length). Ptr is used where the
elements of the array are pointers to CBase
-derived
objects.
RArray
classes
in preference to the CArrayX classes. The exception to this rule is
when the array is likely to be resized often - in which case you might
use one of the segmented variants. Symbian provides a number of templated
associative arrays: RHashMap
- associative array with key type
K and value type V, using a probe-sequence hash table. Both the key
and value objects are copied into the table when they are added. A
bitwise binary copy is used here, so neither of the types K and V
may implement a nontrivial copy constructor.
RPtrHashSet
- unordered extensional set
of objects of type T
using a probe-sequence hash
table. The objects are not copied into the set when they are added;
rather the set stores pointers to the contained objects.
RPtrHashMap
- an associative array with
key type K and value type V, using a probe-sequence hash table. Neither
the key nor value objects are copied into the table when they are
added - only pointers are stored.
In addition to the Symbian C++ array classes, you can also use STL containers provided by Open C and Open C++.
Qt allows you to use STL containers, or to use its own general purpose template-based container classes. The Qt classes are designed to be lighter, safer and easier to use than STL classes. They are implicitly shared, reentrant, and thread-safe in situations where they are used as read-only containers by all threads used to access them.
Qt provides both sequential containers (QList
,QLinkedList
, QVector
, QStack
, and QQueue
), and associative containers
(QMap
, QMultiMap
, QHash
, QMultiHash
, and QSet
). There
are also specialist classes like QCache
and QContiguousCache
that provide efficient hash-lookup of objects
in a limited cache storage, and non-template specialisations like QStringList
(inherits from QListQList<QString>
) that make it easier to work with lists of strings.
The containers
can be traversed using either java-style or STL-style iterators, or
using the convenient foreach
keyword. Qt provides
a set of Generic Algorithms that you can use to sort,
find, fill, count, delete items in the container (on container types
that have an STL iterator).
The template classes store items of a specified type T. The value type T can be a basic type, a pointer type, a class that has a default constructor, a copy constructor and an assignment operator, or a container that meets the same criteria as a class.
The Qt container classes are well documented in the Qt reference: Container classes. There is also an excellent discussion in C++ GUI Programming with Qt 4 , Second Edition, Jasmin Blanchette and Mark Summerfield, Prentice Hall (2006) (the first edition is available free online here).
There is no need to convert container/lists if you're using the standard STL containers, as these are supported by both Qt and the Symbian platform.
If you do need to convert between Qt and Symbian arrays, this usually
a matter of iterating through one container, converting each contained
object into the correct type for the environment (e.g. QString
vs descriptor), and then adding it to the new container.
When converting to Qt, QList
is the best "general
use" re-sizable container template if you have less than 1000 items
(its implemented as an array-list but provides very fast prepends
and appends). If you're working with lists of strings, use QStringList
instead. When converting to Symbian C++, use
a descriptor array for strings, or RArray
for other
objects that are greater than 4 bytes in size (unless you're expecting
a lot of array re-sizing).
The following fragment shows conversion
of a set of integers from an RArray
to a QList
:
RArray<TInt> intArrayToList; QList<int> integerList; ... for (int i = 0; i < count; i++) { integerList.append(intArrayToList[i]); }
This fragment shows a QList of integers being imported
into an RArray
, using foreach
to
iterate the QList
. Note that a TInt
is typdef of signed int
:
QList<int> integerList; RArray<TInt> listToIntArray; ... foreach (int integerItem, integerList) { listToIntArray.Append(integerItem); }
Converting lists of strings uses exactly the same
approach, except that you use a QStringList
rather
than a QList
, a descriptor array instead of an RArray
, and you need to convert the contained string to
the correct format for the environment, as discussed in the Strings
sections of Converting strings and buffers between Symbian and Qt.
The following code shows how CDesCArrayFlat
is
converted to QStringList
:
CDesCArrayFlat* arrayToStringList; ... QStringList qlistOfStrings; for (int i = 0; i < count; i++) { qlistOfStrings.append(QString::fromUtf16( arrayToStringList->MdcaPoint(i).Ptr(), arrayToStringList->MdcaPoint(i).Length())); }
Most of the material in this topic is based with permission on a Symbian Foundation wiki article Apps:Using Qt and Symbian C++ Together . The version used was that available at Symbian Foundation on 3 November 2010. The content in this page is licensed under the Creative Commons Attribution-Share Alike 2.0 UK: England & Wales License (http://creativecommons.org/licenses/by-sa/2.0/uk).