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


請先 登入 以發表留言。