Microsoft的公司在MFC中提供的類別CList,在資列結構中就是串列,如果以手工製造串列,加入、刪除,存取,動態配置記憶體加上指標,會有點複雜,學生時代也曾被搞得昏天暗地,一不小心還會產生Memory Leak,電腦怎麼死的都還覺得莫名奇妙。在MFC中提供這個類別,可大大提升效率。還是要提醒,如果你是初入門本科系學生,別投機取巧,還是腳踏實地的「昏天暗地」,這樣才能了解其中的訣竅,那天希望效能更高的時候,要手工打造的時候,才不會手足無措。

CList支援非單一物件串列排序,說明如下:

Template < class TYPE ,class ARG_TYPE = const TYPE& >Class CList:Public CObject

前面的部份是類別樣板(class template),透過這個功能達到型態的變化,中間的部份則是型態引數,最後則是說明繼承(inherit)那個類別,CList是繼承CObject。

參數說明:

TYPE:儲存在這個串列中的物件型態。

ARG_TYPE:使用參考儲存在這串列中物件的型態,可以為一個參考值。

補充說明:

CList是雙向串列。POSITION是變數型態,用來作為串列的鍵值。你可使用POSITION的變數來當作指標(iterator),想像成指標會比較容易,想不出來如何翻譯。用這個巡迴在串列中,也可以當作標籤指向某個特定位置,跟索引值(index)不同。

元素如果要插入串列的開頭、結尾的位置或是一個已知的位置,速度非常快,如果需要藉著某一個值或索引(原文使用index,可是我覺得用POSITON會比較好)來循序尋找的話,在串列很長的時候,這速度就會很慢。

如果你要取出元素時,你就必須設定取出元素的個數(depth),從1開始或是更大。

 

 


CList Members:

建構子

CList 建構一個空串列

Head/Tail Access:

GetHead 返回串列開頭元素(串列不能是空的)。
GetTail 返回串列結尾元素(串列不能是空的)。

Operations:

AddHead 加一個新的元素(或是另外一個串列)到串列的開頭。
AddTail 加一個新的元素(或是另外一個串列)到串列的結尾。
RemoveAll 移除串列中所有的元素。
RemoveHead 移除串列開頭的元素。
RemoveTail 移除串列結尾的元素。

Iteration:

GetHeadPosition 返回串列開頭的元素位置(POSITION)。
GetNext 取得指標(iterator)下一個元素。
GetPrev 取得指標(iterator)前一個元素。
GetTailPosition 返回串列結尾元素的位置(POSITION)。

Retrieval/Modification:

GetAt 取得指定位置(POSITION)元素。
RemoveAt 移除指定位置(POSITION)元素。
SetAt 設定指定位置(POSITION)元素。

Insertion:

InsertAfter 插入元素至指定位置(POSITION)之後。
InsertBefore 插入元素至指定位置(POSITION)之前。

 

Searching:

Find 取得指定指標值元素位置(POSITION)。
FindIndex 取得指定(以0起始)索引值元素位置(POSITION)。

Status:

GetCount 返回串列元素的個數。
GetSize 返回串列元素的個數。
IsEmpty 測試串列是否為無任何元素狀態。

 

標頭檔:
afxtempl.h

範例:
// MFC_CList.cpp : 定義主控台應用程式的進入點。
//

#include "stdafx.h"
#include <iostream>

#include <afxtempl.h>

//-----------------------------------------------------------

//要使用CList一定要將afxtempl.h包含進來,
//並且專案屬性中的「MFC的使用」也要設定
#include <afxtempl.h>

//-----------------------------------------------------------

using namespace std;


int _tmain(int argc, _TCHAR* argv[])
{
 CList<int,int&> CL_Int_Data;

 int Int_Temp,Int_Loop1;
 POSITION Pos_Temp;

 //-----------------------------------------------------------
 
 cout<<"驗證 IsEmpty、GetCount、GetSize"<<endl;
 //IsEmpty:檢測是否為空串列

 Int_Temp=CL_Int_Data.IsEmpty();
 if(Int_Temp==1)
 {
  cout<<"目前是空的串列"<<endl;
 }

 //-----------------------------------------------------------

 //GetCount:檢測目前串列大小
 Int_Temp=CL_Int_Data.GetCount();
 cout<<"目前串列所含元素數目(GetCount):"<<Int_Temp<<endl;

 //GetSize:檢測目前串列大小
 Int_Temp=CL_Int_Data.GetSize();
 cout<<"目前串列所含元素數目(GetSize):"<<Int_Temp<<endl;

 cout<<endl<<endl;

 //-----------------------------------------------------------

 cout<<"驗證 AddHead、AddTail"<<endl;

 //AddHead:往頭的方向加入新元素
 Int_Temp=1;
 CL_Int_Data.AddHead(Int_Temp);
 
 Int_Temp=2;
 CL_Int_Data.AddHead(Int_Temp);

 //AddTail:往尾的方向加入新元素
 Int_Temp=-1;
 CL_Int_Data.AddTail(Int_Temp);

 Int_Temp=-2;
 CL_Int_Data.AddTail(Int_Temp);

 
 //GetHead:取出開頭位置的內容
 Int_Temp=CL_Int_Data.GetHead();
 cout<<"目前頭的位置內容值(GetHead)(2,1.-1,-2): "<<Int_Temp<<endl;
 
 //GetTail:取出結尾位置的內容
 Int_Temp=CL_Int_Data.GetTail();
 cout<<"目前頭的位置內容值(GetHead)(2,1.-1,-2): "<<Int_Temp<<endl;
 
 
 //IsEmpty:檢測是否為空串列

 Int_Temp=CL_Int_Data.IsEmpty();
 if(Int_Temp==1)
 {
  cout<<"目前是空的串列"<<endl;
 }
 else
 {
  cout<<"目前不是空串列"<<endl;
 }

 //GetCount:檢測目前串列大小
 Int_Temp=CL_Int_Data.GetCount();
 cout<<"目前串列所含元素數目(GetCount):"<<Int_Temp<<endl;

 //GetSize:檢測目前串列大小
 Int_Temp=CL_Int_Data.GetSize();
 cout<<"目前串列所含元素數目(GetSize):"<<Int_Temp<<endl;

 cout<<endl<<endl;

 //-----------------------------------------------------------

 cout<<"驗證 GetHeadPosition、GetNext、GetPrev、GetTailPosition"<<endl;
 cout<<"驗證 GetAt、RemoveAt、SetAt"<<endl;

 //GetHeadPosition:取出串列開頭位置(POSITION)
 Pos_Temp=CL_Int_Data.GetHeadPosition ();
 cout<<"目前開頭位置(POSITION)的內容(GetHeadPosition、GetAt):"<<CL_Int_Data.GetAt (Pos_Temp)<<endl;

 //GetNext(POSTION):以現在位置(括號內的POSITION變數)往下一個位置移動
 CL_Int_Data.GetNext(Pos_Temp);
 cout<<"目前開頭位置(POSITION)移動到下一個位置的元素內容(GetNext、GetAt):"<<CL_Int_Data.GetAt (Pos_Temp)<<endl;
 CL_Int_Data.GetNext(Pos_Temp);
 cout<<"目前位置(POSITION)移動到下一個位置的元素內容(GetNext、GetAt):"<<CL_Int_Data.GetAt (Pos_Temp)<<endl;

 //GetPrev(POSITION):以現在位置(括號內的POSITION變數)往前一個位置移動
 CL_Int_Data.GetPrev (Pos_Temp);
 cout<<"目前位置(POSITION)移動到前一個位置的元素內容(GetPrev、GetAt):"<<CL_Int_Data.GetAt (Pos_Temp)<<endl;


 //GetTailPosition:取出串列結尾位置(POSITION)
 Pos_Temp=CL_Int_Data.GetTailPosition ();
 cout<<"目前結尾位置(POSITION)的內容(GetTailPosition、GetAt):"<<CL_Int_Data.GetAt (Pos_Temp)<<endl;

 //RemoveAt(POSITION):移除本位置元素
 CL_Int_Data.RemoveAt (Pos_Temp);
 Pos_Temp=CL_Int_Data.GetTailPosition ();
 cout<<"移除原結尾元素,目前結尾位置(POSITION)的內容(RemoveAt、GetTailPosition、GetAt):"<<CL_Int_Data.GetAt (Pos_Temp)<<endl;

 //SetAt(POSITION):設定本位置元素
 Int_Temp=100;
 CL_Int_Data.SetAt (Pos_Temp,Int_Temp);
 cout<<"設定目前位置(POSITION)的內容(SetAt、GetAt):"<<CL_Int_Data.GetAt (Pos_Temp)<<endl;

 cout<<endl<<endl;

 //-----------------------------------------------------------
 
 cout<<"驗證 RemoveHead、RemoveTail"<<endl;

 //RemoveHead:移除開頭位置元素
 CL_Int_Data.RemoveHead();

 //GetHead:取出開頭位置的內容
 Int_Temp=CL_Int_Data.GetHead();
 cout<<"目前頭的位置內容值(RemoveHead,GetHead)(1.100): "<<Int_Temp<<endl;
 
 //RemoveTail:移除結尾位置元素
 CL_Int_Data.RemoveTail();

 //GetTail:取出結尾位置的內容
 Int_Temp=CL_Int_Data.GetTail();
 cout<<"目前結尾的位置內容值(RemoveTail,GetTail)(1): "<<Int_Temp<<endl;

 //IsEmpty:檢測是否為空串列

 Int_Temp=CL_Int_Data.IsEmpty();
 if(Int_Temp==1)
 {
  cout<<"目前是空的串列"<<endl;
 }
 else
 {
  cout<<"目前不是空串列"<<endl;
 }

 //GetCount:檢測目前串列大小
 Int_Temp=CL_Int_Data.GetCount();
 cout<<"目前串列所含元素數目(GetCount):"<<Int_Temp<<endl;

 //GetSize:檢測目前串列大小
 Int_Temp=CL_Int_Data.GetSize();
 cout<<"目前串列所含元素數目(GetSize):"<<Int_Temp<<endl;

 cout<<endl<<endl;

 //-----------------------------------------------------------
 
 cout<<"驗證 InsertAfter、InsertBefore"<<endl;

 //InsertAfter:插入一個元素至目前位置的下一個位置
 Pos_Temp=CL_Int_Data.GetHeadPosition ();
 Int_Temp=-3;
 CL_Int_Data.InsertAfter (Pos_Temp,Int_Temp);
 cout<<"串列(InsertAfter)(1,-3)"<<endl;

 Int_Temp=-2;
 CL_Int_Data.InsertAfter (Pos_Temp,Int_Temp);
 cout<<"串列(InsertAfter)(1,-2,-3)"<<endl;

 Int_Temp=-1;
 CL_Int_Data.InsertAfter (Pos_Temp,Int_Temp);
 cout<<"串列(InsertAfter)(1,-1.-2,-3)"<<endl;

 //InsertBefore:插入一個元素至目前位置的前一個位置
 Int_Temp=100;
 CL_Int_Data.InsertBefore (Pos_Temp,Int_Temp);
 cout<<"串列(InsertBefore)(100,1,-1.-2,-3)"<<endl;

 Int_Temp=120;
 CL_Int_Data.InsertBefore (Pos_Temp,Int_Temp);
 cout<<"串列(InsertBefore)(100,120,1,-1.-2,-3)"<<endl;


 //使用回圈將資料讀出
 Pos_Temp=CL_Int_Data.GetHeadPosition ();

 for(Int_Loop1=0;Int_Loop1<6;Int_Loop1++)
 {
  cout<<"串列資料["<<Int_Loop1<<"]="<<CL_Int_Data.GetAt (Pos_Temp)<<endl;
  CL_Int_Data.GetNext (Pos_Temp);
 }

 cout<<endl<<endl;

 //-----------------------------------------------------------
 
 cout<<"驗證 Find、FindIndex"<<endl;
 
 //Find:尋找特定 POSITION
 cout<<"請輸入搜尋資料:";
 cin>>Int_Temp;
 Pos_Temp=CL_Int_Data.Find(Int_Temp);

 if(Pos_Temp==NULL)
 {
  cout<<"未在串列中搜尋到資料"<<endl;
 }
 else
 {
  cout<<"串列資料存在搜尋資料:"<<CL_Int_Data.GetAt (Pos_Temp)<<endl;
 }

 //FindIndex:尋找特定索引值內容
 cout<<"請輸入尋找索引值位置:";
 cin>>Int_Temp;
 Pos_Temp=CL_Int_Data.FindIndex (Int_Temp);
 cout<<"第"<<Int_Temp<<"位置內容值:"<<CL_Int_Data.GetAt (Pos_Temp)<<endl;

 

 system("Pause");

 return 0;
}

 

 


執行結果 1 - 

執行結果 2 - 
 

參考資料:
1. MSDN,CList Class,
https://msdn.microsoft.com/zh-tw/library/bxde0zae(v=VS.100).aspx
2. MSDN,CList Members,https://msdn.microsoft.com/zh-tw/library/0kzd7fcw.aspx

創作者介紹
創作者 向夢想飛行 的頭像
向夢想飛行

向夢想飛行

向夢想飛行 發表在 痞客邦 留言(0) 人氣( 1836 )