ATL 集合類別
ATL 提供許多類別來儲存和存取數據。 您決定使用的類別取決於數個因素,包括:
要儲存的數據量
存取數據的效率與效能
依索引或索引鍵存取數據的能力
如何排序數據
個人喜好設定
小型集合類別
ATL 提供下列陣列類別來處理少量物件。 不過,這些類別會受到限制,且設計供 ATL 在內部使用。 不建議您在程式中使用它們。
類別 | 數據記憶體的類型 |
---|---|
CSimpleArray | 實作陣語別來處理少量物件。 |
CSimpleMap | 實作對應類別來處理少量物件。 |
一般用途集合類別
下列類別會實作陣列、清單和對應,並提供為一般用途集合類別:
類別 | 數據記憶體的類型 |
---|---|
CAtlArray | 實作陣列。 |
CAtlList | 實作清單。 |
CAtlMap | 實作對應結構,其中索引鍵或值可以參考數據。 |
CRBMap | 使用 Red-Black 演算法實作對應結構。 |
CRBMultiMap | 實作紅黑多重對應結構。 |
這些類別會在偵錯組建中使用時攔截許多程式設計錯誤,但為了達到效能,這些檢查將不會在零售組建中執行。
特製化集合類別
也提供更特製化的集合類別來管理記憶體指標和介面指標:
類別 | 目的 |
---|---|
CAutoPtrArray | 提供在建構智慧型指標數位時很有用的方法。 |
CAutoPtrList | 提供在建構智慧型指標清單時很有用的方法。 |
CComUnkArray | IUnknown 儲存指標,並設計為做為 IConnectionPointImpl 範本類別的參數。 |
CHeapPtrList | 提供建構堆積指標清單時很有用的方法。 |
CInterfaceArray | 提供在建構 COM 介面指標陣列時很有用的方法。 |
CInterfaceList | 提供在建構 COM 介面指標清單時很有用的方法。 |
選擇集合類別
每個可用的集合類別都提供不同的效能特性,如下表所示。
數據行 2 和 3 描述每個類別的排序和存取特性。 在下表中,「已排序」一詞是指項目的插入和刪除順序決定其在集合中的順序;而不是指項目依其內容排序。 「已編製索引」一詞是指集合中的項目可由整數索引擷取,就像是一般陣列中的項目。
數據行 4 和 5 描述每個類別的效能。 在需要多次插入集合的應用程式中,插入速度可能特別重要;至於其他應用程式,查閱速度可能比較重要。
欄 6 描述每個圖形是否允許重複的項目。
指定集合類別作業的效能會以完成作業所需的時間與集合中的項目數目之間的關聯性來表示。 作業需要一段時間,隨著元素數目增加而線性增加,則會描述為 O(n) 演算法。 相反地,當元素數目增加時,作業需要一段時間,隨著元素數目增加而減少,則會描述為 O(log n) 演算法。 因此,就效能而言,O(log n) 演算法在元素數目增加時,效能優於 O(n) 演算法。
集合圖形功能
圖形 | 排序 | 索引 | 插入 項目 |
搜尋目標 指定的專案 |
複製 項目 |
---|---|---|---|---|---|
清單 | 是 | No | 快速 (常數時間) | 慢 O(n) | Yes |
陣列 | Yes | 依 int (常數時間) | 慢速 O(n) 除非在結尾插入,在此情況下為常數時間 | 慢 O(n) | Yes |
地圖 | No | 依索引鍵 (常數時間) | 快速 (常數時間) | 快速 (常數時間) | 否 (索引鍵) 是 (值) |
紅黑地圖 | 是 (按索引鍵) | 依索引鍵 O(log n) | Fast O(log n) | Fast O(log n) | No |
Red-Black Multimap | 是 (按索引鍵) | 依索引鍵 O(log n) (每個索引鍵的多個值) | Fast O(log n) | Fast O(log n) | 是 (每個索引鍵有多個值) |
使用 CTraits 物件
由於 ATL 集合類別可用來儲存各種不同的使用者定義數據類型,因此能夠覆寫重要的函式,例如比較很有用。 這是使用 CTraits 類別達成的。
CTraits 類別類似於 MFC 集合類別協助程式函式,但比 MFC 集合類別協助程式函式更有彈性;如需詳細資訊,請參閱 集合類別協助程式 。
建構集合類別時,您可以選擇指定 CTraits 類別。 這個類別會包含程式代碼,這些程式代碼會在由組成集合類別的其他方法呼叫時執行比較等作業。 例如,如果您的清單物件包含您自己的使用者定義結構,您可能想要重新定義相等測試,只比較特定成員變數。 如此一來,清單物件的 Find 方法將會以更有用的方式運作。
範例
程式碼
// Collection class / traits class example.
// This program demonstrates using a CTraits class
// to create a new comparison operator.
#define MAX_STRING 80
// Define our own data type to store in the list.
struct MyData
{
int ID;
TCHAR name[MAX_STRING];
TCHAR address[MAX_STRING];
};
// Define our own traits class, making use of the
// existing traits and overriding only the comparison
// we need.
class MyTraits : public CElementTraits< MyData >
{
public:
// Override the comparison to only compare
// the ID value.
static bool CompareElements(const MyData& element1, const MyData& element2)
{
if (element1.ID == element2.ID)
return true;
else
return false;
};
};
void DoAtlCustomTraitsList()
{
// Declare the array, with our data type and traits class
CAtlList < MyData, MyTraits > MyList;
// Create some variables of our data type
MyData add_item, search_item;
// Add some elements to the list.
add_item.ID = 1;
_stprintf_s(add_item.name, _T("Rumpelstiltskin"));
_stprintf_s(add_item.address, _T("One Grimm Way"));
MyList.AddHead(add_item);
add_item.ID = 2;
_stprintf_s(add_item.name, _T("Rapunzel"));
_stprintf_s(add_item.address, _T("One Grimm Way"));
MyList.AddHead(add_item);
add_item.ID = 3;
_stprintf_s(add_item.name, _T("Cinderella"));
_stprintf_s(add_item.address, _T("Two Grimm Way"));
MyList.AddHead(add_item);
// Create an element which will be used
// to search the list for a match.
search_item.ID = 2;
_stprintf_s(search_item.name, _T("Don't care"));
_stprintf_s(search_item.address, _T("Don't care"));
// Perform a comparison by searching for a match
// between any element in the list, and our
// search item. This operation will use the
// (overridden) comparison operator and will
// find a match when the IDs are the same.
POSITION i;
i = MyList.Find(search_item);
if (i != NULL)
_tprintf_s(_T("Item found!\n"));
else
_tprintf_s(_T("Item not found.\n"));
}
註解
如需 CTraits 類別的清單,請參閱 集合類別。
下圖顯示 CTraits 類別的類別階層。
集合類別範例
下列範例示範集合類別: