访问集合的所有成员
MFC 数组集合类(无论是否基于模板)使用索引来访问其元素。 MFC 列表和映射集合类(无论是否基于模板)使用 POSITION 类型的指示器来描述集合内的给定位置。 若要访问这些集合的一个或多个成员,首先初始化位置指示器,然后重复将此位置传递给集合,使其返回下一个元素。 集合不负责维护迭代进度的状态信息。 该信息保存在位置指示器。 但对于给定的特定位置,集合负责返回下一个元素。
下面的过程演示如何循环访问 MFC 提供的三种主要类型集合:
循环访问数组
使用按次序的索引号与
GetAt
成员函数:CTypedPtrArray<CObArray, CPerson *> myArray; myArray.Add(new CPerson()); for (int i = 0; i < myArray.GetSize(); i++) { CPerson *thePerson = myArray.GetAt(i); thePerson->AssertValid(); }
此示例使用一个类型化的指针数组,其中包含指向
CPerson
对象的指针。 数组派生自CObArray
类,这是一个非模板预定义类。GetAt
返回一个指向CPerson
对象的指针。 对于类型化的指针集合类(数组或列表),第一个参数指定基类;第二个参数指定要存储的类型。CTypedPtrArray
类还重载 [ ] 运算符,这样你可以使用常用的数组下标语法来访问数组的元素。 以上for
循环正文中的语句的替代是CPerson *thePerson = myArray[i];
此运算符同时存在于
const
和非const
版本中。const
版本(为const
数组调用)仅可在赋值语句右侧出现。
循环访问列表
使用成员函数
GetHeadPosition
和GetNext
来访问列表:CTypedPtrList<CObList, CPerson *> myList; myList.AddHead(new CPerson()); POSITION pos = myList.GetHeadPosition(); while (pos != NULL) { CPerson *thePerson = myList.GetNext(pos); thePerson->AssertValid(); }
此示例使用一个类型化的指针列表,包含指向
CPerson
对象的指针。 列表声明类似于 循环访问数组 步骤中数组的列表声明,但它派生自CObList
类。GetNext
返回一个指向CPerson
对象的指针。
循环访问映射
使用
GetStartPosition
来到映射的开头,使用GetNextAssoc
反复获取映射中的下一个键和值,如下所示:CMap<CString, LPCTSTR, CPerson *, CPerson *> myMap; CPerson myPerson; myMap.SetAt(_T("Bill"), &myPerson); POSITION pos = myMap.GetStartPosition(); while (pos != NULL) { CPerson *pPerson; CString string; // Get key (string) and value (pPerson) myMap.GetNextAssoc(pos, string, pPerson); // Use string and pPerson }
此示例使用简单的映射模板(而不是类型化的指针集合),该模板使用
CString
键,并存储指向CPerson
对象的指针。 当使用访问函数(如GetNextAssoc
)时,该类提供了指向CPerson
对象的指针。 如果改为使用非模板映射集合之一,则必须将返回的CObject
指针转换为指向CPerson
的指针。注意
对于非模板映射,编译器需要最后一个
CObject
参数中GetNextAssoc
指针的引用。 在输入时,必须将指针转换为类型,如下例所示。模板解决方案更简单,可帮助提高类型安全性。 非模板代码更复杂一些,正如你在这里看到的:
CMapStringToOb myMap; // A nontemplate collection class CPerson myPerson; myMap.SetAt(_T("Bill"), &myPerson); POSITION pos = myMap.GetStartPosition(); while (pos != NULL) { CPerson *pPerson; CString string; // Gets key (string) and value (pPerson) myMap.GetNextAssoc(pos, string, (CObject *&)pPerson); ASSERT(pPerson->IsKindOf(RUNTIME_CLASS(CPerson))); // Use string and pPerson ... }
有关详细信息,请参阅 删除 CObject 集合中的所有对象。