Symbian 学习日志(七. 向量的使用)

本文介绍了一种使用CArrayX和RArrayX系列类管理动态数组的方法,包括不同类型数组的特点、内存配置方式,以及通过示例展示了如何实现任务管理器,进行任务的增删改查等操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、各种类型缀名称说明:

 

保存类型:

Fix: 元素的实例占用的内存大小是相同,并且会将对象拷贝到向量中;

Var: 元素大小可以不相同,并且只是将元素的指针放到向量中;

Pak: 元素大小可以不同同,并且拷贝了元素的内容,是以长度+内容来保存的;

Ptr: 保存从CBase派生元素指针;

 

内存配置:

Flat: 连续内存; 类似: Array

Seg: 不连续内存;类似: List

 

如下图所示:

 CArrayX Memory

 

二、 具体类的功能查看帮助,派生图如下:

 

CArrayX

 

三、CArrayX 使用例子:

 

class TTask // Basic T class, represents a task

{

public:

      TTask(const TDesC& aTaskName);

      void ExecuteTaskL() {}; // Omitted for clarity

private:

      TBuf<10> iTaskName;

};

TTask::TTask(const TDesC& aTaskName)

{ iTaskName.Copy(aTaskName); }

// Holds a dynamic array of TTask pointers

class CTaskManager : public CBase

{

public:

      static CTaskManager* NewLC();

      ~CTaskManager();

public:

      void AddTaskL(TTask* aTask);

      void InsertTaskL(TTask* aTask, TInt aIndex);

      void RunAllTasksL();

      void DeleteTask(TInt aIndex);

public:

      inline TInt Count()

      {return (iTaskArray->Count());};

      inline TTask* GetTask(TInt aIndex)

      {return(iTaskArray->At(aIndex));};

private:

      void ConstructL();

      CTaskManager() {};

private:

      CArrayPtrSeg<TTask>* iTaskArray;

};

const TInt KTaskArrayGranularity = 5;

CTaskManager* CTaskManager::NewLC()

{

      CTaskManager* me = new (ELeave) CTaskManager();

      CleanupStack::PushL(me);

      me->ConstructL();

      return (me);

}

CTaskManager::()

{// Cleanup the array

      if (iTaskArray)

           iTaskArray->ResetAndDestroy(); // Destroys objects through ptrs

      delete iTaskArray;

}

void CTaskManager::ConstructL()

{

      iTaskArray =

           new (ELeave) CArrayPtrSeg<TTask>(KTaskArrayGranularity);

}

void CTaskManager::AddTaskL(TTask* aTask)

{ // Add a task to the end of array

      // No need to check that aTask! =NULL because CBufBase does this

      // before appending it

      iTaskArray->AppendL(aTask);

}

void CTaskManager::InsertTaskL(TTask* aTask, TInt aIndex)

{ // Insert a task into a given element index

      // No assertion on aTask or aIndex because CArrayFixBase

      // and CBufBase do this

      iTaskArray->InsertL(aIndex, aTask);

}

void CTaskManager::RunAllTasksL()

{ // Iterates all TTask objects and calls ExecuteTaskL()

      TInt taskCount = iTaskArray->Count();

      for (TInt index = 0; index < taskCount; index++)

      {

           (*iTaskArray)[index]->ExecuteTaskL();

      }

}

void CTaskManager::DeleteTask(TInt aIndex)

{ // Removes the pointer from the array

      // The function stores a pointer to it so it can be destroyed

      TTask* task = iTaskArray->At(aIndex);

      if (task)

      {

           iTaskArray->Delete(aIndex); // Does not delete the object

           delete task; // Deletes the object

      }

}

// Calling code

void TestTaskManagerL()

{

      CTaskManager* taskManager = CTaskManager::NewLC();

      // Add four tasks to the array

      _LIT(KTaskName, "TASKX%u");

      for (TInt index =0; index<4; index++)

      {

           TBuf<10> taskName;

           taskName.Format(KTaskName, index); // Names each task

           TTask* task = new (ELeave) TTask(taskName);

           CleanupStack::PushL(task);

           taskManager->AddTaskL(task);

           CleanupStack::Pop(task); // Now owned by the taskManager array

      }

      ASSERT(4==taskManager->Count()); // Chapter 16 discusses ASSERTs

      // Insert a task into element 3

      _LIT(KNewTask, "InsertedTask");

      TTask* insertedTask = new (ELeave) TTask(KNewTask);

      CleanupStack::PushL(insertedTask);

      taskManager->InsertTaskL(insertedTask, 3);

      CleanupStack::Pop(insertedTask); // Now owned by taskManager

      ASSERT(5==taskManager->Count());

      // Delete a task

      taskManager->DeleteTask(2);

      ASSERT(4==taskManager->Count());

      taskManager->RunAllTasksL();

      // Destroys the array (which itself destroys the TTasks it owns)

      CleanupStack::PopAndDestroy(taskManager);

}

 

四、RArray<T> and RPointerArray

 

class TTask // Basic T class, represents a task

{

public:

      TTask(const TDesC& aTaskName);

      void ExecuteTaskL() {}; // Omitted for clarity

private:

      TBuf<10> iTaskName;

};

TTask::TTask(const TDesC& aTaskName)

{ iTaskName.Copy(aTaskName); }

// Holds a dynamic array of TTask pointers

class CTaskManager : public CBase

{

public:

      static CTaskManager* NewLC();

      ~CTaskManager();

public:

      void AddTaskL(TTask* aTask);

      void InsertTaskL(TTask* aTask, TInt aIndex);

      void RunAllTasksL();

      void DeleteTask(TInt aIndex);

public:

      inline TInt Count()

      {return (iTaskArray->Count());};

      inline TTask* GetTask(TInt aIndex)

      {return(iTaskArray->At(aIndex));};

private:

      void ConstructL();

      CTaskManager() {};

private:

      CArrayPtrSeg<TTask>* iTaskArray;

};

const TInt KTaskArrayGranularity = 5;

CTaskManager* CTaskManager::NewLC()

{

      CTaskManager* me = new (ELeave) CTaskManager();

      CleanupStack::PushL(me);

      me->ConstructL();

      return (me);

}

CTaskManager::()

{// Cleanup the array

      if (iTaskArray)

           iTaskArray->ResetAndDestroy(); // Destroys objects through ptrs

      delete iTaskArray;

}

void CTaskManager::ConstructL()

{

      iTaskArray =

           new (ELeave) CArrayPtrSeg<TTask>(KTaskArrayGranularity);

}

void CTaskManager::AddTaskL(TTask* aTask)

{ // Add a task to the end of array

      // No need to check that aTask! =NULL because CBufBase does this

      // before appending it

      iTaskArray->AppendL(aTask);

}

void CTaskManager::InsertTaskL(TTask* aTask, TInt aIndex)

{ // Insert a task into a given element index

      // No assertion on aTask or aIndex because CArrayFixBase

      // and CBufBase do this

      iTaskArray->InsertL(aIndex, aTask);

}

void CTaskManager::RunAllTasksL()

{ // Iterates all TTask objects and calls ExecuteTaskL()

      TInt taskCount = iTaskArray->Count();

      for (TInt index = 0; index < taskCount; index++)

      {

           (*iTaskArray)[index]->ExecuteTaskL();

      }

}

void CTaskManager::DeleteTask(TInt aIndex)

{ // Removes the pointer from the array

      // The function stores a pointer to it so it can be destroyed

      TTask* task = iTaskArray->At(aIndex);

      if (task)

      {

           iTaskArray->Delete(aIndex); // Does not delete the object

           delete task; // Deletes the object

      }

}

// Calling code

void TestTaskManagerL()

{

      CTaskManager* taskManager = CTaskManager::NewLC();

      // Add four tasks to the array

      _LIT(KTaskName, "TASKX%u");

      for (TInt index =0; index<4; index++)

      {

           TBuf<10> taskName;

           taskName.Format(KTaskName, index); // Names each task

           TTask* task = new (ELeave) TTask(taskName);

           CleanupStack::PushL(task);

           taskManager->AddTaskL(task);

           CleanupStack::Pop(task); // Now owned by the taskManager array

      }

      ASSERT(4==taskManager->Count()); // Chapter 16 discusses ASSERTs

      // Insert a task into element 3

      _LIT(KNewTask, "InsertedTask");

      TTask* insertedTask = new (ELeave) TTask(KNewTask);

      CleanupStack::PushL(insertedTask);

      taskManager->InsertTaskL(insertedTask, 3);

      CleanupStack::Pop(insertedTask); // Now owned by taskManager

      ASSERT(5==taskManager->Count());

      // Delete a task

      taskManager->DeleteTask(2);

      ASSERT(4==taskManager->Count());

      taskManager->RunAllTasksL();

      // Destroys the array (which itself destroys the TTasks it owns)

      CleanupStack::PopAndDestroy(taskManager);

}

四、使用RArrayX 系列:

 

      RArray在调用结束后要调用Close Reset 来清除。RArrray 可以存在 stack 也可以是在heap

       使用原则:尽量使用 RArray  而不是CArrayX,除非是要支持非连续存取和不同大小的对象的存取。

 

R 类的使用

class TTask // Basic T class, represents a task

{

public:

      TTask(const TDesC& aTaskName);

      void ExecuteTaskL() {}; // Omitted for clarity

private:

      TBuf<10> iTaskName;

};

 

TTask::TTask(const TDesC& aTaskName)

{

      iTaskName.Copy(aTaskName);

}

 

/**

*  CTaskManager

*

*/

class CTaskManager : public CBase

{

public: // Constructors and destructor

 

      /**

        * Destructor.

        */

      ~CTaskManager();

 

        /**

        * Two-phased constructor.

        */

      static CTaskManager* NewL();

 

        /**

        * Two-phased constructor.

        */

      static CTaskManager* NewLC();

 

      ~CCTaskManager();

 

public:

      void AddTaskL(TTask* aTask);

      void InsertTaskL(TTask* aTask, TInt aIndex);

      void RunAllTasksL();

      void DeleteTask(TInt aIndex);

 

public:

      inline TInt Count()

      {return (iTaskArray->Count());};

      inline TTask* GetTask(TInt aIndex)

      {return(iTaskArray->At(aIndex));};

 

private:

 

      /**

        * Constructor for performing 1st stage construction

        */

      CTaskManager() {}

 

      /**

        * EPOC default constructor for performing 2nd stage construction

        */

      void ConstructL();

 

private:

      CArrayPtrSeg<TTask>* iTaskArray;

};

 

#endif // TASKMANAGER_H

 

class TTask // Basic T class, represents a task

{

public:

      TTask(const TDesC& aTaskName, const TInt aPriority);

      ...

public:

      static TInt ComparePriorities(const TTask& aTask1,

           const TTask& aTask2);

      static TBool Match(const TTask& aTask1, const TTask& aTask2);

private:

      TBuf<10> iTaskName;

      TInt iPriority;

};

TTask::TTask(const TDesC& aTaskName, const TInt aPriority)

: iPriority(aPriority){iTaskName.Copy(aTaskName);}

// Returns 0 if both are equal priority,

// Returns a negative value if aTask1 > aTask2

// Returns a positive value if aTask1 < aTask2

TInt TTask::ComparePriorities(const TTask& aTask1, const TTask& aTask2)

{

      if (aTask1.iPriority>aTask2.iPriority)

           return (-1);

      else if (aTask1.iPriority<aTask2.iPriority)

           return (1);

      else

           return (0);

}

// Compares two tasks; returns ETrue if both iTaskName and

// iPriority are identical

TBool TTask::Match(const TTask& aTask1, const TTask& aTask2)

{

      if ((aTask1.iPriority==aTask2.iPriority) &&

           (aTask1.iTaskName.Compare(aTask2.iTaskName)==0))

      {

           return (ETrue);

      }

      return (EFalse);

}

class CTaskManager : public CBase

      // Holds a dynamic array of TTask pointers

{

public:

      static CTaskManager* NewLC();

      ();

public:

      void AddTaskL(TTask& aTask);

      void InsertTaskL(TTask& aTask, TInt aIndex);

      void RunAllTasksL();

      void DeleteTask(TInt aIndex);

      void DeleteTask(const TTask& aTask);

public:

      inline TInt Count() {return (iTaskArray.Count());};

      inline TTask& GetTask(TInt aIndex) {return(iTaskArray[aIndex]);};

private:

      CTaskManager() {};

private:

      RArray<TTask> iTaskArray;

};

CTaskManager::()

{// Close the array (free the memory associated with the entries)

      iTaskArray.Close();

}

void CTaskManager::AddTaskL(TTask& aTask)

{// Add a task to the end of array

      User::LeaveIfError(iTaskArray.Append(aTask));

}

void CTaskManager::InsertTaskL(TTask& aTask, TInt aIndex)

{// Insert a task in a given element

      User::LeaveIfError(iTaskArray.Insert(aTask, aIndex));

}

void CTaskManager::RunAllTasksL()

{// Sorts the tasks into priority order then iterates through them

      // and calls ExecuteTaskL() on each

      // Construct a temporary TLinearOrder object implicitly –the

      // equivalent of the following:

      // iTaskArray.Sort(TLinearOrder<TTask>(TTask::ComparePriorities));

      iTaskArray.Sort(TTask::ComparePriorities);

      TInt taskCount = iTaskArray.Count();

      for (TInt index = 0; index < taskCount; index++)

      {

           iTaskArray[index].ExecuteTaskL();

      }

}

void CTaskManager::DeleteTask(const TTask& aTask)

{// Removes all tasks identical to aTask from the array

      // Constructs a temporary TIdentityRelation object implicitly –the

      // equivalent of the following:

      // TInt foundIndex = iTaskArray.Find(aTask,

      // TIdentityRelation<TTask>(TTask::Match));

      while (TInt foundIndex = iTaskArray.Find(aTask,

           TTask::Match)! =KErrNotFound)

      {

           iTaskArray.Remove(foundIndex);

      }

}

void CTaskManager::DeleteTask(TInt aIndex)

{// Removes the task at index aIndex from the array

      iTaskArray.Remove(aIndex);

}

 

void TestTaskManagerL()

{

      CTaskManager* taskManager = CTaskManager::NewLC();

      // Add tasks to the array, use the index to set the task priority

      _LIT(KTaskName, "TASKX%u");

      for (TInt index=0; index<4; index++)

      {

           TBuf<10> taskName;

           taskName.Format(KTaskName, index);

           TTask task(taskName, index);

           taskManager->AddTaskL(task);

      }

      ASSERT(4==taskManager->Count());

      // Add a copy of the task at index 2

      // to demonstrate sorting and matching

      TBuf<10> taskName;

      taskName.Format(KTaskName, 2);

      TTask copyTask(taskName, 2);

      taskManager->AddTaskL(copyTask);

      ASSERT(5==taskManager->Count());

      taskManager->RunAllTasksL();

      // Remove both copies of the task

      taskManager->DeleteTask(copyTask);

      ASSERT(3==taskManager->Count());

      // Destroy the taskManager

      CleanupStack::PopAndDestroy(taskManager);

}

 

五、内置的字符串向量

      CPtrCArray, CDesCArray, CDesCArrayFlat, CDesCArraySeg

 

六、固定元素个数组类

 

TFixedArray,当元素个数是固定个数的时候,应该使用TFixedArray.

 

class TTask

{

public:

      TTask(TInt aPriority);

public:

      TInt iPriority;

};

TTask::TTask(TInt aPriority)

: iPriority(aPriority){}

void TestFixedArray()

{

      TTask tasks[5]={TTask(0), TTask(1), TTask(2), TTask(3), TTask(4)};

      // Wrap tasks with a range-checked TFixedArray

      TFixedArray<TTask, 5> taskArray(&tasks[0], 5);

      taskArray[1].iPriority = 3; // change priority

      taskArray[5].iPriority = 3;

      // Assertion fails -> panics debug builds (USER 133)

      taskArray.At(5).iPriority = 3;

      // Assertion fails -> panics debug & release builds

}

 

七、存二进制数据的向量

      CBufFlat CBufSeg,存取二进制文件,可以动态分配大小;

 

      // Returns random data in an 8-bit heap descriptor of length = aLength

HBufC8* GetRandomDataLC(TInt aLength); // Defined elsewhere

void PrintBufferL(CBufBase* aBuffer)

{

      aBuffer->Compress();

      // Compress to free unused memory at the end of a segment

      TInt length = aBuffer->Size();

      HBufC8* readBuf = HBufC8::NewL(length);

      TPtr8 writable(readBuf->Des());

      aBuffer->Read(0, writable);

      ... // Omitted. Print to the console

      delete readBuf;

}

void TestBuffersL()

{

      __UHEAP_MARK; // Heap checking macro to test for memory leaks

      CBufBase* buffer = CBufSeg::NewL(16); // Granularity = 16

      CleanupStack::PushL(buffer); // There is no NewLC() function

      HBufC8* data = GetRandomDataLC(32);// Data is on the cleanup stack

      buffer->InsertL(0, *data);

      // Destroy original. A copy is now stored in the buffer

      CleanupStack::PopAndDestroy(data);

      PrintBufferL(buffer);

      buffer->ExpandL(0, 100); // Pre-expand the buffer

      TInt pos = 0;

      for (TInt index = 0; index <4; index++, pos+16)

      {// Write the data in several chunks

           data = GetRandomDataLC(16);

           buffer->Write(pos, *data);

           CleanupStack::PopAndDestroy(data); // Copied so destroy here

      }

      PrintBufferL(buffer);

      CleanupStack::PopAndDestroy(buffer); // Clean up the buffer

      __UHEAP_MARKEND; // End of heap checking

}

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值