Классы на основе шаблонов

В этой статье описываются классы коллекций на основе шаблонов на основе типов в MFC версии 3.0 и более поздних версиях. Использование этих шаблонов для создания типобезопасных коллекций удобнее и помогает обеспечить безопасность типов более эффективно, чем использование классов коллекций, не основанных на шаблонах.

MFC предопределяет две категории коллекций на основе шаблонов:

Простые классы коллекции являются производными от класса 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. Для массивов используйте либо CObArrayCPtrArray. Для списков используйте или CObListCPtrList.

В действительности при объявлении коллекции на основе, скажем 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, CMapWordToPtrCMapStringToObи т. д. 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, а не указатель или ссылку на тип, класс или структура должны иметь конструктор копирования.

Дополнительные сведения см. в статье "Создание коллекции Сейф типа".

См. также

Коллекции