Поделиться через


Классы Template-Based

В этой статье объясняются типобезопасные коллекции на основе шаблонов в 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

Чтобы использовать шаблоны коллекций с типизированными указателями, необходимо знать, какие типы данных можно хранить в этих коллекциях и какие параметры следует использовать в объявлениях коллекции.

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, или использовать типобезопасный оператор [ ].

Второй пример объявляет список указателей с заданным типом, myList, созданный на основе CPtrList. Список хранит и возвращает указатели на MY_STRUCT объекты. Класс, основанный на CPtrList, используется для хранения указателей на объекты, не являющиеся производными от CObject. CTypedPtrList имеет ряд функций элементов, безопасных для типов: GetHead, GetTail, RemoveHead, RemoveTail, GetNext, GetPrevи GetAt.

Использование карты Typed-Pointer

Класс карты с типизированным указателем CTypedPtrMap принимает три параметра: BASE_CLASS, KEY и VALUE. Параметр BASE_CLASS указывает класс, из которого следует наследовать новый класс: CMapPtrToWord, , CMapPtrToPtrCMapStringToPtr, 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.

Замечание

Если указать тип class или struct для параметра VALUE, а не указатель или ссылка на тип, класс или структура должны иметь конструктор копирования.

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

См. также

коллекции