This document covers the important issues involved in using an RArray.
By convention, class
names starting with the letter R
do not allocate memory on
the heap. RArray
<class T>
is an exception and
this should be remembered when using the class.
If an array is declared
on the program stack, then its Close()
or Reset()
member
function must be called to ensure that allocated memory is freed.
Similarly,
if RArray<class T>
is a data member of another class,
then the destructor of that class must call Close()
or Reset()
.
A RArray<class
T>
array allows its contained objects to be ordered. The array provides
the behaviour for inserting and sorting instances of the template class T
.
To help with this, the template class T
must provide an algorithm
for deciding how two class T
objects are ordered. This algorithm
is implemented by a function which must be wrapped in a TLinearOrder<class
T>
package.
The function implementing the algorithm can be
a static member of the class T
but need not necessarily be
so.
Here, we aim to build an array of TMyTest
objects
ordered in a way which makes sense for the TMyTest
class.
class TMyTest { public : TMyTest(TInt anAint,TInt aBint); static TInt Compare(const TMyTest& aFirst, const TMyTest& Second); public: TInt a; TInt b; };
In this example , the algorithm is implemented by a static
function called Compare()
. It takes const references to two TMyTest
objects
and returns zero if the objects are equal, a negative value if aFirst
is
less than aSecond
and a positive value if aFirst
is
greater than aSecond
.
TInt TMyTest::Compare(const TMyTest& aFirst,const TMyTest& aSecond) { if (aFirst.b < aSecond.b) return -1; if (aFirst.b > aSecond.b) return 1; return 0; }
Construct three TMyTest
objects and then
construct an array object for an array of TMyTest
objects;
the array has default granularity.
TMyTest one(1,1); TMyTest two(2,2); TMyTest three(3,3); ... RArray<TMyTest> x;
There are at least three ways of proceeding, some of which are more efficient than others.
... TLinearOrder<TMyTest> order(TMyTest::Compare); ... x.InsertInOrder(one,order); ...
... x.InsertInOrder(one,TLinearOrder<TMyTest>(TMyTest::Compare)); ...
... x.InsertInOrder(one,TMyTest::Compare); ...
This applies to all member functions of RArray<class
T>
which take a TLinearOrder<class T>
argument.
One of the Find()
member
functions of RArray<class T>
takes a TIdentityRelation<class
T>
as an argument. This packages a function which implements
an algorithm for deciding whether two class T
objects match.
The
packaging technique is the same as for the previous section. As an example,
we can extend the class TMyTest
used in Packaging the algorithm for ordering array objects by adding another
static function called Match()
.
class TMyTest { public : TMyTest(TInt anAint,TInt aBint); static TInt Compare(const TMyTest& aFirst, const TMyTest& Second); static TBool Match(const TMyTest& aFirst, const TMyTest& Second); public: TInt a; TInt b; };
A typical implementation for Match()
might
be:
TBool TMyTest::Match(const TMyTest& aFirst,const TMyTest& aSecond) { if ((aFirst.a == aSecond.a) && (aFirst.b == aSecond.b)) return ETrue; return EFalse; }
So, given an array:
RArray<TMyTest> x;RArray<TMyTest> x;
populated with a number TMyTest
objects, we can packageTMyTest
's
matching function in at least three ways.
... TIdentityRelation<TMyTest> matcher(TMyTest::Match); ... TMyTest hunter(9,9); TInt index = x.Find(hunter,order); if (index == KErrNotFound) { ... } ...
... TMyTest hunter(9,9); TInt index = x.Find(hunter,TIdentityRelation<TMyTest>(TMyTest::Match)); if (index == KErrNotFound) { ... } ...
... TMyTest hunter(9,9); TInt index = x.Find(hunter,TMyTest::Match); if (index == KErrNotFound) { ... } ...