ATL – třídy kolekce
ATL poskytuje mnoho tříd pro ukládání a přístup k datům. Která třída, kterou se rozhodnete použít, závisí na několika faktorech, mezi které patří:
Množství dat, která se mají uložit
Efektivita versus výkon při přístupu k datům
Možnost přístupu k datům pomocí indexu nebo klíče
Jak jsou data seřazená
Osobní preference
Třídy malých kolekcí
ATL poskytuje následující třídy pole pro práci s malým počtem objektů. Tyto třídy jsou však omezené a navržené pro interní použití atL. Nedoporučujeme je používat ve svých programech.
Třída | Typ úložiště dat |
---|---|
CSimpleArray | Implementuje třídu pole pro práci s malým počtem objektů. |
CSimpleMap | Implementuje mapovací třídu pro práci s malým počtem objektů. |
Třídy kolekce pro obecné účely
Následující třídy implementují pole, seznamy a mapy a jsou poskytovány jako třídy kolekce pro obecné účely:
Třída | Typ úložiště dat |
---|---|
CAtlArray | Implementuje pole. |
Seznam CAtl | Implementuje seznam. |
CAtlMap | Implementuje strukturu mapování, kde na data lze odkazovat pomocí klíče nebo hodnoty. |
CRBMap | Implementuje strukturu mapování pomocí algoritmu Red-Black. |
CRBMultiMap | Implementuje strukturu multimappingu red-black. |
Tyto třídy zachytí mnoho programovacích chyb při použití v ladicích buildech, ale kvůli výkonu se tyto kontroly neprovedou v maloobchodních buildech.
Specializované třídy kolekcí
Pro správu ukazatelů paměti a ukazatelů rozhraní jsou k dispozici také specializované třídy kolekcí:
Třída | Účel |
---|---|
CAutoPtrArray | Poskytuje metody užitečné při vytváření pole inteligentních ukazatelů. |
CAutoPtrList | Poskytuje užitečné metody při vytváření seznamu inteligentních ukazatelů. |
CComUnkArray | Ukládá IUnknown ukazatele a je navržena jako parametr třídy šablony IConnectionPointImpl . |
CHeapPtrList | Poskytuje metody užitečné při vytváření seznamu ukazatelů haldy. |
CInterfaceArray | Poskytuje metody užitečné při vytváření pole ukazatelů rozhraní MODELU COM. |
CInterfaceList | Poskytuje metody užitečné při vytváření seznamu ukazatelů rozhraní MODELU COM. |
Výběr třídy kolekce
Každá z dostupných tříd kolekcí nabízí různé charakteristiky výkonu, jak je znázorněno v následující tabulce.
Sloupce 2 a 3 popisují vlastnosti řazení a přístupu jednotlivých tříd. Výraz "objednaný" v tabulce znamená, že pořadí, ve kterém jsou položky vloženy a odstraněny, určuje jejich pořadí v kolekci; neznamená, že položky jsou seřazené v jejich obsahu. Výraz "indexed" znamená, že položky v kolekci lze načíst celočíselnou indexou, podobně jako položky v typickém poli.
Sloupce 4 a 5 popisují výkon jednotlivých tříd. V aplikacích, které vyžadují mnoho vložení do kolekce, může být rychlost vkládání obzvláště důležitá; pro jiné aplikace může být důležitější rychlost vyhledávání.
Sloupec 6 popisuje, jestli každý obrazec umožňuje duplicitní prvky.
Výkon dané operace třídy kolekce je vyjádřen z hlediska vztahu mezi časem potřebným k dokončení operace a počtem prvků v kolekci. Operace trvá nějakou dobu, která se lineárně zvyšuje, protože počet prvků se zvyšuje, je popsán jako algoritmus O(n). Naproti tomu operace trvá určité časové období, které se zvyšuje méně a méně, protože se počet prvků zvyšuje, popisuje se jako algoritmus O(log n). Z hlediska výkonu proto algoritmy O(log n) přesáhly algoritmy O(n) více a více s tím, jak se zvyšuje počet prvků.
Funkce obrazce kolekce
Tvar | Objednáno | Indexovaný | Vložení – element |
Vyhledat zadaný prvek |
Duplikát elementy |
---|---|---|---|---|---|
List | Yes | No | Rychlé (konstantní čas) | Pomalé O(n) | Ano |
Pole | Ano | Podle int (konstantní čas) | Pomalé O(n) s výjimkou případů vložení na konec, v takovém případě konstantního času | Pomalé O(n) | Ano |
Map | No | Podle klíče (konstantní čas) | Rychlé (konstantní čas) | Rychlé (konstantní čas) | Ne (klíče) Ano (hodnoty) |
Červenočerná mapa | Ano (podle klíče) | Podle klíče O(log n) | Rychlé O(log n) | Rychlé O(log n) | No |
Červenočerná multimapa | Ano (podle klíče) | Podle klíče O(log n) (více hodnot na klíč) | Rychlé O(log n) | Rychlé O(log n) | Ano (více hodnot na klíč) |
Použití objektů CTraits
Protože třídy kolekce ATL lze použít k ukládání široké škály uživatelsky definovaných datových typů, může být užitečné přepsat důležité funkce, jako jsou porovnání. Toho se dosahuje pomocí tříd CTraits.
Třídy CTraits jsou podobné, ale flexibilnější než pomocné funkce třídy kolekce MFC; Další informace najdete v tématu Pomocné rutiny tříd kolekce.
Při vytváření třídy kolekce máte možnost zadat CTraits třídy. Tato třída bude obsahovat kód, který bude provádět operace, jako jsou porovnání při volání jinými metodami, které tvoří třídu kolekce. Pokud například objekt seznamu obsahuje vlastní uživatelem definované struktury, můžete předefinovat test rovnosti tak, aby porovnával pouze určité členské proměnné. Tímto způsobem bude metoda Find objektu seznamu fungovat užitečnějším způsobem.
Příklad
Kód
// 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"));
}
Komentáře
Seznam tříd CTraits naleznete v tématu Třídy kolekce.
Následující diagram znázorňuje hierarchii tříd pro třídy CTraits.
Ukázky tříd kolekcí
Následující ukázky ukazují třídy kolekcí: