RPointerArray<class T>
By convention, class names starting with the letter R
do not allocate memory on the heap. RPointerArray<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 RPointerArray<class T>
is a data
member of another class, then the destructor of that class must call
Close()
or Reset()
.
Another issue to remember is the ownership of objects whose
pointers are contained within an RPointerArray<class T>
array. If ownership of the objects lies elsewhere, then calling
Close()
or Reset()
before the array goes out of scope
is sufficient. If, however, ownership of these objects is vested in the array,
and it is the intention that these objects be destroyed when the array is
destroyed, then ResetAndDestroy()
must be called before the array
goes out of scope.
A RPointerArray<class T>
array allows its
contained pointers to be ordered so that the objects themselves are in object
order. The array provides the behaviour for inserting and sorting instances of
pointers to the template class. To help with this, the template class must
provide an algorithm for deciding how two template class 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 but need not necessarily be so.
Here, we aim to build an array of CMyTest
objects
ordered in a way which makes sense for the CTMyTest
class.
class CMyTest
{
public
~CMyTest();
Static CMytest* NewL(const TDesC& aText);
static TInt Compare(const CMyTest& aFirst, const CMyTest& Second);
public:
HBufC* iText;
};
In this example, the algorithm is implemented by a static function
called Compare()
. It takes const references to two
CMyTest
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 CMyTest::Compare(const CMyTest& aFirst,const CMyTest& aSecond)
{
TInt ret = (aFirst.iText)->Compare(*aSecond.iText);
if (ret > 0)
return 1;
if (ret < 0)
return -1;
return 0;
}
Construct three CMyTest
objects and then construct an
array object for an array of pointers to CMyTest
objects; the
array has default granularity.
_LIT(KTextOne,"First Text");
_LIT(KTextTwo,"Second Text");
_LIT(KTextThree,"Third Text");
...
CMyTest* one = CMyTest::NewL(KTextOne);
CMyTest* two = CMyTest::NewL(KTextTwo);
CMyTest* three = CMyTest::NewL(KTextThree);
...
RPointerArray<CMyTest> x;
There are at least three ways of proceeding, some of which are more efficient than others.
Explicitly build a TLinearOrder<CMyTest>
and
pass this as a parameter to InsertInOrder()
.
...
TLinearOrder<CMyTest> order(CMyTest::Compare);
...
x.InsertInOrder(one,order);
...
Construct a temporary TLinearOrder<CMyTest>
on the call to InsertInOrder()
.
...
x.InsertInOrder(one,TLinearOrder<CMyTest>(CMyTest::Compare));
...
Implicitly construct a temporary
TLinearOrder<CMyTest>
on the call to
InsertOrder()
.
...
x.InsertInOrder(one,CMyTest::Compare);
...
This applies to all member functions of
RPointerArray<class T>
which take a
TLinearOrder<class T>
argument.