Klasy oparte na szablonach
W tym artykule opisano klasy kolekcji oparte na szablonach bezpieczne dla typów w MFC w wersji 3.0 lub nowszej. Użycie tych szablonów do tworzenia kolekcji bezpiecznych typów jest wygodniejsze i pomaga zapewnić bezpieczeństwo typów bardziej efektywnie niż używanie klas kolekcji nie opartych na szablonach.
MFC wstępnie zdefiniowane dwie kategorie kolekcji opartych na szablonach:
Proste klasy tablic, listy i map
CArray
,CList
,CMap
Tablice, listy i mapy wpisanych wskaźników
CTypedPtrArray
,CTypedPtrList
,CTypedPtrMap
Wszystkie proste klasy kolekcji pochodzą z klasy CObject
, więc dziedziczą serializacji, tworzenia dynamicznego i innych właściwości klasy CObject
. Klasy kolekcji wskaźników typowych wymagają określenia klasy pochodzącej z klasy — która musi być jedną z kolekcji wskaźników niepamiętnych wstępnie zdefiniowanych przez MFC, takich jak CPtrList
lub CPtrArray
. Nowa klasa kolekcji dziedziczy z określonej klasy bazowej, a funkcje składowe nowej klasy używają hermetyzowanych wywołań do składowych klasy bazowej w celu wymuszania bezpieczeństwa typów.
Aby uzyskać więcej informacji na temat szablonów języka C++, zobacz Szablony w dokumentacji języka C++.
Używanie prostych szablonów tablic, list i map
Aby użyć prostych szablonów kolekcji, musisz wiedzieć, jakiego rodzaju dane można przechowywać w tych kolekcjach i jakie parametry mają być używane w deklaracjach kolekcji.
Użycie prostej tablicy i listy
Proste klasy tablic i list, CArray i CList, przyjmują dwa parametry: TYPE i ARG_TYPE
. Te klasy mogą przechowywać dowolny typ danych określony w parametrze TYPE :
Podstawowe typy danych języka C++, takie jak
int
,char
ifloat
Struktury i klasy języka C++
Inne typy, które definiujesz
Dla wygody i wydajności można użyć parametru ARG_TYPE , aby określić typ argumentów funkcji. Zazwyczaj należy określić ARG_TYPE jako odwołanie do typu nazwanego w parametrze TYPE . Przykład:
CArray<int, int> myArray;
CList<CPerson, CPerson &> myList;
W pierwszym przykładzie zadeklarowana jest kolekcja tablic , myArray
która zawiera **int
s. Drugi przykład deklaruje kolekcję list , myList
która przechowuje CPerson
obiekty. Niektóre funkcje składowe klas kolekcji przyjmują argumenty, których typ jest określony przez parametr szablonu ARG_TYPE . Na przykład Add
funkcja składowa klasy CArray
przyjmuje argument ARG_TYPE :
CArray<CPerson, CPerson &> personArr;
CPerson person;
personArr.Add(person);
Proste użycie mapy
Prosta klasa mapy, CMap, przyjmuje cztery parametry: KEY, ARG_KEY, VALUE i ARG_VALUE. Podobnie jak w przypadku klas tablic i list, klasy map mogą przechowywać dowolny typ danych. W przeciwieństwie do tablic i list, które indeksują i porządkują przechowywane dane, mapują skojarzyć klucze i wartości: uzyskujesz dostęp do wartości przechowywanej na mapie, określając skojarzony klucz wartości. Parametr KEY określa typ danych kluczy używanych do uzyskiwania dostępu do danych przechowywanych na mapie. Jeśli typ KLUCZA jest strukturą lub klasą, parametr ARG_KEY jest zazwyczaj odwołaniem do typu określonego w kluczu. Parametr VALUE określa typ elementów przechowywanych na mapie. Jeśli typ ARG_VALUE jest strukturą lub klasą, parametr ARG_VALUE jest zazwyczaj odwołaniem do typu określonego w wartości. Przykład:
CMap<int, int, MY_STRUCT, MY_STRUCT &> myMap1;
CMap<CString, LPCTSTR, CPerson, CPerson &> myMap2;
Pierwszy przykład przechowuje MY_STRUCT
wartości, uzyskuje do nich dostęp za pomocą int
kluczy i zwraca dostęp do elementów MY_STRUCT
według odwołania. Drugi przykład przechowuje CPerson
wartości, uzyskuje do nich dostęp za pomocą CString
kluczy i zwraca odwołania do elementów, do których uzyskuje się dostęp. Ten przykład może reprezentować prostą książkę adresową, w której wyszukujesz osoby według nazwiska.
Ponieważ parametr KEY jest typuCString
, a parametr KEY_TYPE jest typu LPCSTR
, klucze są przechowywane na mapie jako elementy typuCString
, ale są przywołyne w funkcjach, takich jak SetAt
wskaźniki typu LPCSTR
. Przykład:
CMap<CString, LPCTSTR, CPerson, CPerson &> myMap;
CPerson person;
LPCTSTR lpstrName = _T("Jones");
myMap.SetAt(lpstrName, person);
Używanie szablonów kolekcji typu wskaźnik
Aby użyć szablonów kolekcji typu wskaźnik, musisz wiedzieć, jakie rodzaje danych można przechowywać w tych kolekcjach i jakie parametry mają być używane w deklaracjach kolekcji.
Tablica wskaźników typu i użycie listy
Typd-pointer tablicy i klas list, CTypedPtrArray i CTypedPtrList, przyjmują dwa parametry: BASE_CLASS i TYPE. Te klasy mogą przechowywać dowolny typ danych określony w parametrze TYPE . Pochodzą one z jednej z nieplaterowych klas kolekcji, które przechowują wskaźniki; należy określić tę klasę bazową w BASE_CLASS. W przypadku tablic użyj polecenia CObArray
lub CPtrArray
. W przypadku list użyj polecenia CObList
lub CPtrList
.
W efekcie, po zadeklarowaniu kolekcji na podstawie, powiedzmy CObList
, nowa klasa nie tylko dziedziczy elementy członkowskie swojej klasy bazowej, ale także deklaruje szereg dodatkowych funkcji składowych i operatorów bezpiecznych typów, które pomagają zapewnić bezpieczeństwo typów przez hermetyzowanie wywołań do składowych klasy bazowej. Te hermetyzacji zarządzają wszystkimi niezbędnymi konwersjami typów. Przykład:
CTypedPtrArray<CObArray, CPerson *> myArray;
CTypedPtrList<CPtrList, MY_STRUCT *> myList;
Pierwszy przykład deklaruje tablicę typu-wskaźnik, myArray
, pochodzącą z CObArray
klasy . Tablica przechowuje i zwraca wskaźniki do CPerson
obiektów (gdzie CPerson
jest klasą pochodzącą z CObject
klasy ). Można wywołać dowolną CObArray
funkcję składową lub wywołać nową funkcję bezpieczną GetAt
i ElementAt
typową lub użyć operatora safe [ ] .
W drugim przykładzie zadeklarowano listę wskaźników typu , myList
pochodzącą z CPtrList
klasy . Lista przechowuje i zwraca wskaźniki do MY_STRUCT
obiektów. Klasa oparta na CPtrList
jest używana do przechowywania wskaźników do obiektów, które nie pochodzą z CObject
klasy . CTypedPtrList
ma szereg funkcji składowych bezpiecznych typów: GetHead
, , GetTail
, RemoveHead
RemoveTail
, GetNext
, GetPrev
i GetAt
.
Typizowane użycie mapy wskaźnika
Typd-pointer, klasa mapy, CTypedPtrMap, przyjmuje trzy parametry: BASE_CLASS, KEY i VALUE. Parametr BASE_CLASS określa klasę, z której ma pochodzić nowa klasa: CMapPtrToWord
, , CMapStringToPtr
CMapPtrToPtr
, CMapWordToPtr
, CMapStringToOb
i tak dalej. KLUCZ jest analogiczny do klucza w pliku CMap
: określa typ klucza używanego do wyszukiwania. WARTOŚĆ jest analogiczna do wartości w elemecie CMap
: określa typ obiektu przechowywanego na mapie. Przykład:
CTypedPtrMap<CMapPtrToPtr, CString, MY_STRUCT*> myPtrMap;
CTypedPtrMap<CMapStringToOb, CString, CPerson*> myPersonMap;
Pierwszy przykład to mapa oparta na CMapPtrToPtr
— używa CString
kluczy mapowanych do wskaźników do MY_STRUCT
. Możesz wyszukać przechowywany wskaźnik, wywołując funkcję składową bezpieczną Lookup
dla typu. Możesz użyć operatora [ ] , aby wyszukać przechowywany wskaźnik i dodać go, jeśli nie zostanie znaleziony. I można iterować mapę przy użyciu funkcji bezpiecznej GetNextAssoc
typu. Można również wywołać inne funkcje składowe klasy CMapPtrToPtr
.
Drugi przykład to mapa oparta na CMapStringToOb
— używa kluczy ciągów mapowanych do przechowywanych wskaźników do CMyObject
obiektów. Można użyć tych samych składowych bezpiecznych typów opisanych w poprzednim akapicie lub wywołać elementy członkowskie klasy CMapStringToOb
.
Uwaga
Jeśli określisz class
typ lub struct
dla parametru VALUE , a nie wskaźnik lub odwołanie do typu, klasa lub struktura musi mieć konstruktor kopiujący.
Aby uzyskać więcej informacji, zobacz How to Make a Type-Sejf Collection (Jak utworzyć kolekcję typu Sejf).