Классы на основе шаблонов
В этой статье описываются классы коллекций на основе шаблонов на основе типов в MFC версии 3.0 и более поздних версиях. Использование этих шаблонов для создания типобезопасных коллекций удобнее и помогает обеспечить безопасность типов более эффективно, чем использование классов коллекций, не основанных на шаблонах.
MFC предопределяет две категории коллекций на основе шаблонов:
Простые классы массива, списка и карты
CArray
,CList
,CMap
Массивы, списки и карты типизированных указателей
CTypedPtrArray
,CTypedPtrList
,CTypedPtrMap
Простые классы коллекции являются производными от класса CObject
, поэтому они наследуют сериализацию, динамическое создание и другие свойства CObject
. Классы коллекции типизированного указателя требуют указания класса, наследуемого от него, который должен быть одной из коллекций указателей, предопределенных MFC, таких как CPtrList
или CPtrArray
. Новый класс коллекции наследует от указанного базового класса, а функции-члены нового класса используют инкапсулированные вызовы членов базового класса для обеспечения безопасности типов.
Дополнительные сведения о шаблонах C++ см. в справочнике по языкам C++.
Использование простых шаблонов массивов, списков и карт
Чтобы использовать простые шаблоны коллекций, необходимо знать, какие данные можно хранить в этих коллекциях и какие параметры следует использовать в объявлениях коллекции.
Простое использование массива и списка
Простые классы массивов и списков, CArray и CList, принимают два параметра: TYPE и ARG_TYPE
. Эти классы могут хранить любой тип данных, указанный в параметре TYPE :
Основные типы данных C++, такие как
int
,char
иfloat
Структуры и классы C++
Другие типы, которые вы определяете
Для удобства и эффективности можно использовать параметр ARG_TYPE , чтобы указать тип аргументов функции. Как правило, вы указываете ARG_TYPE в качестве ссылки на тип, который вы назвали в параметре TYPE . Например:
CArray<int, int> myArray;
CList<CPerson, CPerson &> myList;
В первом примере объявляется коллекция массивов, myArray
содержащая **int
**. Второй пример объявляет коллекцию списков, myList
в которой хранятся CPerson
объекты. Некоторые функции-члены классов коллекции принимают аргументы, тип которого указан параметром шаблона ARG_TYPE . Например, Add
функция-член класса CArray
принимает аргумент ARG_TYPE :
CArray<CPerson, CPerson &> personArr;
CPerson person;
personArr.Add(person);
Простое использование карты
Простой класс карты CMap принимает четыре параметра: KEY, ARG_KEY, VALUE и ARG_VALUE. Как и классы массива и списка, классы карты могут хранить любой тип данных. В отличие от массивов и списков, которые индексируют и упорядочивали данные, сопоставляют ключи и значения: вы обращаетесь к значению, хранящееся на карте, задав связанный ключ значения. Параметр KEY указывает тип данных ключей, используемых для доступа к данным, хранящимся на карте. Если тип KEY является структурой или классом, параметр ARG_KEY обычно является ссылкой на тип, указанный в KEY. Параметр VALUE указывает тип элементов, хранящихся в карте. Если тип ARG_VALUE является структурой или классом, параметр ARG_VALUE обычно является ссылкой на тип, указанный в VALUE. Например:
CMap<int, int, MY_STRUCT, MY_STRUCT &> myMap1;
CMap<CString, LPCTSTR, CPerson, CPerson &> myMap2;
Первый пример сохраняет MY_STRUCT
значения, обращается к ним по int
ключам и возвращает доступ к элементам MY_STRUCT
по ссылке. Второй пример сохраняет CPerson
значения, обращается к ним по CString
ключам и возвращает ссылки на доступ к элементам. Этот пример может представлять простую адресную книгу, в которой вы ищете лиц по фамилии.
Так как параметр KEY имеет типCString
, а параметр KEY_TYPE имеет типLPCSTR
, ключи хранятся в карте как элементы типаCString
, но ссылаются в функциях, таких как SetAt
указатели типаLPCSTR
. Например:
CMap<CString, LPCTSTR, CPerson, CPerson &> myMap;
CPerson person;
LPCTSTR lpstrName = _T("Jones");
myMap.SetAt(lpstrName, person);
Использование шаблонов коллекций typed-pointer
Чтобы использовать шаблоны коллекций с типизированными указателями, необходимо знать, какие типы данных можно хранить в этих коллекциях и какие параметры следует использовать в объявлениях коллекции.
Типизированный массив указателей и использование списка
Типизированный массив и классы списков CTypedPtrArray и CTypedPtrList принимают два параметра: BASE_CLASS и TYPE. Эти классы могут хранить любой тип данных, указанный в параметре TYPE . Они являются производными от одного из классов коллекции nontemplate, в которых хранятся указатели; Этот базовый класс указывается в BASE_CLASS. Для массивов используйте либо CObArray
CPtrArray
. Для списков используйте или CObList
CPtrList
.
В действительности при объявлении коллекции на основе, скажем CObList
, новый класс не только наследует члены базового класса, но и объявляет ряд дополнительных функций и операторов, которые помогают обеспечить безопасность типов, инкапсулируя вызовы членов базового класса. Эти инкапсулы управляют всеми необходимыми преобразованиями типов. Например:
CTypedPtrArray<CObArray, CPerson *> myArray;
CTypedPtrList<CPtrList, MY_STRUCT *> myList;
Первый пример объявляет массив типизированного указателя, myArray
производный от CObArray
. Массив сохраняет и возвращает указатели на CPerson
объекты (где CPerson
является класс, производный от CObject
). Можно вызвать любую CObArray
функцию-член или вызвать новый типобезопасный GetAt
и ElementAt
функции или использовать оператор type-safe [ ] .
Второй пример объявляет список типизированного указателя, myList
производный от CPtrList
. Список хранит и возвращает указатели на MY_STRUCT
объекты. Класс, основанный на CPtrList
этом, используется для хранения указателей на объекты, не производные от CObject
. CTypedPtrList
имеет ряд функций элементов, безопасных для типов: GetHead
, GetTail
, RemoveHead
, RemoveTail
, GetNext
, GetPrev
и GetAt
.
Использование карты с типизированным указателем
Класс карты с типизированным указателем CTypedPtrMap принимает три параметра: BASE_CLASS, KEY и VALUE. Параметр BASE_CLASS задает класс, из которого следует наследовать новый класс: CMapPtrToWord
, CMapPtrToPtr
, CMapStringToPtr
, CMapWordToPtr
CMapStringToOb
и т. д. KEY аналогиен ключу вCMap
: указывает тип ключа, используемого для поиска. ЗНАЧЕНИЕ аналогично ЗНАЧЕНИю CMap
в: указывает тип объекта, хранящегося в карте. Например:
CTypedPtrMap<CMapPtrToPtr, CString, MY_STRUCT*> myPtrMap;
CTypedPtrMap<CMapStringToOb, CString, CPerson*> myPersonMap;
Первый пример — это карта на основе CMapPtrToPtr
— он использует CString
ключи, сопоставленные с указателями MY_STRUCT
. Вы можете найти сохраненный указатель, вызвав функцию-член с безопасностью Lookup
типа. Оператор [ ] можно использовать для поиска сохраненного указателя и добавления его, если он не найден. И вы можете итерировать карту с помощью функции, безопасной GetNextAssoc
для типа. Вы также можете вызывать другие функции-члены класса CMapPtrToPtr
.
Второй пример — это карта на основе CMapStringToOb
— он использует строковые ключи, сопоставленные с сохраненными указателями на CMyObject
объекты. Вы можете использовать те же типобезопасные элементы, описанные в предыдущем абзаце, или вызвать членов класса CMapStringToOb
.
Примечание.
Если указать или struct
тип class
параметра VALUE, а не указатель или ссылку на тип, класс или структура должны иметь конструктор копирования.
Дополнительные сведения см. в статье "Создание коллекции Сейф типа".