Using RArray<class T>

This document covers the important issues involved in using an RArray.

Freeing all memory before the array goes out of scope

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().

Packaging the algorithm for ordering array objects

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.

  • Explicitly build a TLinearOrder<TMyTest> and pass this as a parameter to InsertInOrder().

...
TLinearOrder<TMyTest> order(TMyTest::Compare);
...
x.InsertInOrder(one,order);
...
  • Construct a temporary TLinearOrder<TMyTest> on the call to InsertInOrder().

...
x.InsertInOrder(one,TLinearOrder<TMyTest>(TMyTest::Compare));
...
  • Implicitly construct a temporary TLinearOrder<TMyTest> on the call to InsertOrder().

...
x.InsertInOrder(one,TMyTest::Compare);
...

This applies to all member functions of RArray<class T> which take a TLinearOrder<class T> argument.

Packaging the algorithm for matching array objects

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.

  • Explicitly build a TIdentityRelation<TMyTest> and pass this as a parameter to Find(); for example:

...
TIdentityRelation<TMyTest> matcher(TMyTest::Match);
...
TMyTest hunter(9,9);
TInt index = x.Find(hunter,order);
if (index == KErrNotFound)
 {
 ...
 }
...
  • Construct a temporary TIdentityRelation<TMyTest> on the call to Find().

...
TMyTest hunter(9,9);
TInt index = x.Find(hunter,TIdentityRelation<TMyTest>(TMyTest::Match));
if (index == KErrNotFound)
 {
 ...
 }
...
  • Implicitly construct a temporary TIdentityRelation<TMyTest> on the call to Find().

...
TMyTest hunter(9,9);
TInt index = x.Find(hunter,TMyTest::Match);
if (index == KErrNotFound)
 {
 ...
 }
...