Sdílet prostřednictvím


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

  1. Deklarujte proměnnou typu třídy kolekce. Příklad:

    CList<int, int> m_intList;
    
  2. Volejte členské funkce objektu kolekce. Příklad:

    m_intList.AddTail(100);
    m_intList.RemoveAll();
    
  3. 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 CArrayCLista 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ů

CArrayVolání , CLista 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, DWORDa 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:

  1. V případě potřeby používejte netemplatní kolekce s přetypování typů. Jedná se o jednodušší přístup.

  2. Odvozuje a rozšiřuje netemplatovou kolekci typu safe.

Použití netemplatních kolekcí s přetypování typů

  1. Použijte jednu z netemplatních tříd, například CWordArraypří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 z CObject. Kolekce CObList je definována tak, aby držela ukazatele na CObject. Při načtení objektu ze seznamu může být nutné přetypovat výsledek na správný typ, protože CObList funkce vracejí ukazatele na CObject. Pokud například ukládáte CPerson objekty do CObList kolekce, musíte přetypovat načtený prvek tak, aby byl ukazatelem CPerson na objekt. Následující příklad používá kolekci CObList 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

  1. 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 funkce AddHeadPerson obálky a GetHeadPerson, 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 pro GetHeadPerson 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.

Viz také

Kolekce