Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этой статье объясняются типобезопасные коллекции на основе шаблонов в MFC версии 3.0 и более поздних версиях. Использование этих шаблонов для создания типобезопасных коллекций удобнее и помогает обеспечить безопасность типов более эффективно, чем использование классов коллекций, не основанных на шаблонах.
MFC предопределяет две категории коллекций на основе шаблонов:
Простые классы массива, списка и карты
CArray, ,CListCMapМассивы, списки и карты типизированных указателей
CTypedPtrArray, ,CTypedPtrListCTypedPtrMap
Простые классы коллекции являются производными от класса 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".