Postupy: Příprava typově bezpečné kolekce
Tento článek vysvětluje, jak vytvářet typově bezpečné kolekce pro vaše vlastní datové typy. Témata:
Knihovna tříd Microsoft Foundation poskytuje předdefinované kolekce bezpečné pro typy založené na šablonách jazyka C++. Vzhledem k tomu, že se jedná o šablony, tyto třídy pomáhají zajistit bezpečnost typů a snadné použití bez přetypování typů a dalších dodatečných prací spojených s používáním třídy nontemplate pro tento účel. Ukázka MFC COLLECT ukazuje použití tříd kolekcí založených na šablonách v aplikaci MFC. Obecně tyto třídy používejte pokaždé, když napíšete nový kód kolekcí.
Použití tříd založených na šablonách pro typ Sejf ty
Použití tříd založených na šablonách
Deklarujte proměnnou typu třídy kolekce. Příklad:
CList<int, int> m_intList;
Volejte členské funkce objektu kolekce. Příklad:
m_intList.AddTail(100); m_intList.RemoveAll();
V případě potřeby implementujte pomocné funkce a SerializeElements. Informace o implementaci těchto funkcí naleznete v tématu Implementace pomocných funkcí.
Tento příklad ukazuje deklaraci seznamu celých čísel. Prvním parametrem v kroku 1 je typ dat uložených jako prvky seznamu. Druhý parametr určuje, jak mají být data předána a vrácena z členských funkcí třídy kolekce, například Add
a GetAt
.
Implementace pomocných funkcí
Třídy kolekcí založené na šablonách CArray
CList
a CMap
používají pět globálních pomocných funkcí, které můžete přizpůsobit podle potřeby pro odvozenou třídu kolekce. Informace o těchto pomocných funkcích naleznete v tématu Pomocné rutiny třídy kolekce v referenční dokumentaci MFC. Implementace serializační funkce je nezbytná pro většinu použití tříd kolekce založené na šabloně.
Serializace elementů
CArray
Volání , CList
a CMap
třídy SerializeElements
ukládat elementy kolekce nebo číst z archivu.
Výchozí implementace pomocné funkce bitové zápisy SerializeElements
z objektů do archivu nebo bitové čtení z archivu do objektů v závislosti na tom, zda jsou objekty uloženy nebo načteny z archivu. Přepsat SerializeElements
, pokud tato akce není vhodná.
Pokud kolekce ukládá objekty odvozené CObject
a používáte IMPLEMENT_SERIAL
makro v implementaci třídy elementu collection, můžete využít výhod serializace funkce integrované do CArchive
a CObject
:
CArray< CPerson, CPerson& > personArray;
template <> void AFXAPI SerializeElements <CPerson>(CArchive& ar,
CPerson* pNewPersons, INT_PTR nCount)
{
for (int i = 0; i < nCount; i++, pNewPersons++)
{
// Serialize each CPerson object
pNewPersons->Serialize(ar);
}
}
Přetížené operátory vložení pro CArchive
volání CObject::Serialize
(nebo přepsání této funkce) pro každý CPerson
objekt.
Použití tříd kolekce nontemplate
MFC také podporuje třídy kolekcí zavedené v prostředí MFC verze 1.0. Tyto třídy nejsou založené na šablonách. Mohou být použity k zahrnutí dat podporovaných typů CObject*
, UINT
, DWORD
a CString
. Tyto předdefinované kolekce (například CObList
) můžete použít k uložení kolekcí všech objektů odvozených z CObject
. MFC také poskytuje další předdefinované kolekce pro uložení primitivních typů, jako UINT
jsou ukazatele void (void*
). Obecně je však často užitečné definovat vlastní kolekce bezpečné pro typ, které obsahují objekty konkrétnější třídy a jeho deriváty. Všimněte si, že s třídami kolekce, které nejsou založené na šablonách, je více práce než použití tříd založených na šablonách.
Existují dva způsoby, jak vytvořit kolekce bezpečné pro typy s netemplate kolekcemi:
V případě potřeby používejte netemplatní kolekce s přetypování typů. Jedná se o jednodušší přístup.
Odvozuje a rozšiřuje netemplatovou kolekci typu safe.
Použití netemplatních kolekcí s přetypování typů
Použijte jednu z netemplatních tříd, například
CWordArray
přímo.Můžete například vytvořit
CWordArray
a přidat do ní všechny 32bitové hodnoty a pak je načíst. Není nic dalšího k dispozici. Jenom použijete předdefinovanou funkci.Můžete také použít předdefinovanou kolekci, například
CObList
, k uložení libovolných objektů odvozených zCObject
. KolekceCObList
je definována tak, aby držela ukazatele naCObject
. Při načtení objektu ze seznamu může být nutné přetypovat výsledek na správný typ, protožeCObList
funkce vracejí ukazatele naCObject
. Pokud například ukládáteCPerson
objekty doCObList
kolekce, musíte přetypovat načtený prvek tak, aby byl ukazatelemCPerson
na objekt. Následující příklad používá kolekciCObList
k uloženíCPerson
objektů:CPerson* p1 = new CPerson(); CObList myList; myList.AddHead(p1); // No cast needed CPerson* p2 = (CPerson*)myList.GetHead();
Tato technika použití předdefinovaného typu kolekce a přetypování podle potřeby může být vhodná pro mnoho vašich potřeb kolekce. Pokud potřebujete další funkce nebo větší bezpečnost typů, použijte třídu založenou na šabloně nebo postupujte podle dalšího postupu.
Odvození a rozšíření netemplatové kolekce bezpečného typu
Odvozujte vlastní třídu kolekce z jedné z předdefinovaných netemplatních tříd.
Při odvození třídy můžete přidat typově bezpečné obálkové funkce, které poskytují typově bezpečné rozhraní pro existující funkce.
Pokud jste například odvozili seznam z
CObList
objektů pro blokováníCPerson
objektů, můžete přidat funkceAddHeadPerson
obálky aGetHeadPerson
, jak je znázorněno níže.class CPersonList : public CObList { public: void AddHeadPerson(CPerson* person) { AddHead(person); } const CPerson* GetHeadPerson() { return (CPerson*)GetHead(); } };
Tyto funkce obálky poskytují typově bezpečný způsob, jak přidat a načíst
CPerson
objekty z odvozeného seznamu. Vidíte, že proGetHeadPerson
funkci jednoduše zapouzdřujete přetypování typu.Nové funkce můžete také přidat definováním nových funkcí, které rozšiřují možnosti kolekce, a nikoli pouhé zabalení stávajících funkcí do obálky bezpečného typu. Například článek Odstranění všech objektů v kolekci CObject popisuje funkci pro odstranění všech objektů obsažených v seznamu. Tuto funkci lze přidat do odvozené třídy jako členovou funkci.