容器‎ > ‎

cxxlList

list 是簡單又實用的資料結構,只不過這所提供的是針對 cxxlObject 設計的,因此要被包裹的物件必須是 cxxlObjec 的延伸類別。list 算是很普遍的結構,所以也不多做介紹了,以下是結構示意圖:
 
 
 
 以下列出 cxxlList 提供的功能:

基本功能

Push_Front(const Smart_Ptr<T> &S) 將物件放入最前位置
Push_Back(const Smart_Ptr<T> &S) 將物件放入最後位置
Delete_Front() 刪除(放棄持有)最前面一個物件
Delete_Back() 刪除(放棄持有)最後一個物件
GetObj_Front() 取得最前一個物件
GetObj_Back() 取得最後一個物件
Pop_Front() 取出最前一個物件並刪除(放棄持有)
Pop_Back() 取出最後一個物件並刪除(放棄持有)
ClearAll() 刪除(放棄持有)所有物件
GetCount() 取得物件存放的個數

巡行功能

 
ResetPT(PT_PS_TYPE P) 設定指位器至 最前(toHead)或最後(toTail) 的物件位置,非空容器會移到 第一個 或 最後一個 有物件的位置,若是空容器會移到 最後 或 最前 NULL 節點,執行巡行功能前須先執行一次。
operator ++ (int)
operator -- (int)
指位器往後(++)或前(--)的位置移動,並回傳移動前所指的物件
GetObj() 取得指位器目前所指的物件

排序

若須執行排序,應延伸一份自己的 List 類別並覆載 Diagnosis() 這個虛擬函數

Sort() 啟動排序
Diagnosis(const T *P, const T *N) 虛擬函數,排序檢測,延伸類別須改寫此函數, 要讓 P 排在 前(Head) 回答 true,否則 false

自我複製

 若有延伸出自定 List 的類別,且會被用到 Clone(),則應覆載 CreateSelf() 這個虛擬函數,回傳一份自定 List 的實例
Clone() 自我複製,傳回相同內容的同類形容器物件
CreateSelf(ISpirit *spirit) 虛擬函數,Clone() 時用來產生延伸類別的物件,所以有延伸類別且會被用到 Clone(),就必須覆載此函數

基本上 cxxlList 是可當共享物件使用,但以下兩點須注意:

  • 不可以兩個執行緒對同一個物件做巡行功能,最好先複製一份副本,再用副本巡行
  • 執行過排序後,指位器將會被重設到 head 的 NULL 節點
 

範例

#include <iostream>
#include <iomanip> // 內含 I/O 格式控制器
#include <stdlib.h>
#include <time.h>
#include <CXXLLIST.HPP>
using namespace std;
using namespace CxxlMan; 
class A:virtual public cxxlObject
{ 
  int m_i;
public:
  A(int i)
   :cxxlObject(Spirit_Urgent)
  {
    m_i = i;
  }
  virtual ~A()
  { 
  }
  int Get() const
  {
    return m_i;
  }
};
// 提供由小至大排序 A 物件的 list
class MyList:public cxxlList<A>
{
  // 有用到 Clone() 時,用此來產生延伸類別的物件 
  // 所以延伸類別必須覆載
  MyList * cxxlFASTCALL CreateSelf(ISpirit *spirit) const
  { 
    return new MyList; 
  }
  // 使用排序須覆寫這個函數以符合自己的須求
  bool cxxlFASTCALL Diagnosis(const A *P, const A *N) const
  {
    return (P->Get() < N->Get())? true:false;
  }
public:
};
 
int main(int argc, char* argv[])
{
  Smart_Ptr<cxxlList<A> > A_List1(new MyList);
  cout << "產生 10 組亂數放到 A_list1 中:" << endl;
  srand((unsigned)time(NULL));
  for(int i = 0;i < 10; i++)
  {
    int n = rand()%100; 
    A_List1->Push_Back(new A(n));
  }
  Smart_Ptr<cxxlList<A> > A_List2 = A_List1->Clone(); // 複製
  A_List2->Sort(); // 啟動排序
  A_List1->ResetPT(toHead); 
  for(Smart_Ptr<A> A_Ptr = (*A_List1)++; !A_Ptr.isNULL(); A_Ptr = (*A_List1)++)
  {
    cout << setw(2) << setfill('0') << A_Ptr->Get() << " ";
  }
  cout << endl << "A_List2 的內容:" << endl;
  A_List2->ResetPT(toHead); 
  for(Smart_Ptr<A> A_Ptr = (*A_List2)++; !A_Ptr.isNULL(); A_Ptr = (*A_List2)++)
  {
    cout << setw(2) << setfill('0') << A_Ptr->Get() << " ";
  }
  cout << endl;
  system("pause");
}
 
 

 

引入檔

CXXLLIST.HPP

 

程式庫

 

 
 
 
 
 
 
 
 
 
Comments