学习模板和集合类的建议

2020-05-07 09:08

Visual C++ 概念:添加功能

有关选择集合类的建议

本文提供详细信息,以帮助您选择适于特定应用程序需要的集合类。 集合类的选择取决于许多因素,包括:

? ? ? ? ?

类形状的特性:排序、索引和性能,如本主题稍后介绍的集合形状特性表所示 类是否使用 C++ 模板

存储在集合中的元素是否可以序列化 存储在集合中的元素是否可以转储以用于诊断 集合是否是类型安全的

下表集合形状特性总结了可用集合形状的特性。

?

第 2 列和第 3 列描述了每个形状的排序和访问特性。在表中,术语“已排序”表示按插入或删除项的顺序确定项在集合中的顺序,而不是指项按其内容排序。术语“已索引”表示集合中的项可以通过整数索引检索,这和典型数组中的项很相似。

?

第 4 列和第 5 列描述了每个形状的性能。在需要对集合执行多次插入操作的应用程序中,插入速度可能特别重要;而对于其他应用程序,查找速度可能更重要。

?

第 6 列描述了每个形状是否允许重复元素。

集合形状特性

形状 列表 数组 映射 已排序? 是 是 否 已索引? 否 按整数 按键 插入元素 搜索指定元素 快 慢 快 慢 慢 快 重复元素? 是 是 否(键) 是(值) 下表 MFC 集合类的特性总结了特定 MFC 集合类的其他重要特性,可以作为选择原则。您的选择可能取决于特定的因素,如类是否基于 C++ 模板,它的元素是否可以通过 MFC 的文档序列化机制序列化,它的元素是否可以通过 MFC 诊断转储机制转储,类是否是类型安全的,即是否可以保证存储在基于类的集合中和从该集合中检索的元素类型。 MFC 集合类的特性

类 CArray CByteArray CDWordArray CList 使用 C++ 模板 是 否 否 是 可以 序列化 是1 是 是 是1 可以 转储 是1 是 是 是1 类型安全 否 是3 是3 否 CMap CMapPtrToPtr CMapPtrToWord CMapStringToOb CMapStringToPtr 是 否 否 否 否 是1 否 否 是 否 是 是 否 是 是 否 否 是 是 取决于类型2 取决于类型2 取决于类型2 否 是 是1 是 是 是 是 是 是 是 是 是 是 是 是 是 是 是 是 是 是 否 否 否 否 否 是3 否 否 否 否 否 否 是3 是3 是 是 是 是3 是3 CMapStringToString 否 CMapWordToOb CMapWordToPtr CObArray CObList CPtrArray CPtrList CStringArray CStringList CTypedPtrArray CTypedPtrList CTypedPtrMap CUIntArray CWordArray

否 否 否 否 否 否 否 否 是 是 是 否 否 1. 若要序列化,必须显式调用集合对象的 Serialize 函数;若要转储,必须显式调用集合对象的 Dump 函数。不能用 ar << collObj 的形式进行序列化,或用 dmp << collObj 的形式进行转储。

2. 可序列化性取决于基础集合类型。例如,如果类型指针数组基于 CObArray,则它可序列化;如果基于 CPtrArray,则它不可序列化。通常情况下,“Ptr”类无法序列化。

3. 如果该列中的标记为“是”,则只要按本来用途使用非模板集合类,它就是类型安全的。例如,如果将字节存储在 CByteArray 中,则该数组是类型安全的。但如果用该数组存储字符,则它的类型安全不太可靠。

请参见

集合 | 基于模板的类 | 如何创建类型安全集合 | 访问集合的所有成员

基于模板的类

本文解释 MFC 3.0 版及更高版本中类型安全、基于模板的集合类。使用这些模板创建类型安全集合更为方便,并且提供了比使用不基于模板的集合类更高的类型安全。

MFC 预定义了两类基于模板的集合:

?

简单数组、列表和映射类 CArray、CList、CMap

?

类型化指针的数组、列表和映射

CTypedPtrArray、CTypedPtrList、CTypedPtrMap

简单集合类都是从 CObject 类派生的,所以继承了 CObject 的序列化、动态创建以及其他属性。类型指针集合类要求指定派生自的类,该类必须是 MFC 预定义的非模板指针集合之一,如 CPtrList 或 CPtrArray。新的集合类从指定的基类继承,并且新类的成员函数对基类成员使用封装调用以强制类型安全。 有关 C++ 模板的更多信息,请参见 C++ Language Reference 中的模板。

使用简单数组、列表和映射模板

若要使用简单集合模板,需要知道可以在这些集合中存储的数据类型以及集合声明中所使用的参数类型。

简单数组和列表的用法

简单的数组类 CArray 和列表类 CList 采用两个参数:TYPE 和 ARG_TYPE。这些类可以存储任何在 TYPE 参数中指定的数据类型:

? ? ?

基本 C++ 数据类型,如 int、char 和 float C++ 结构和类 定义的其他类型

考虑到方便性和效率,可以使用 ARG_TYPE 参数来指定函数参数的类型。通常情况下,将 ARG_TYPE 指定为对 TYPE 参数中命名类型的引用。例如: 复制代码

CArray myArray; CList myList;

第一个示例声明了一个包含多个 int 的数组集合 myArray。第二个示例声明了一个存储 CPerson 对象的列表集合 myList。集合类的某些成员函数采用其类型由 ARG_TYPE 模板参数指定的参数。例如,CArray 类的 Add 成员函数采用 ARG_TYPE 参数: 复制代码

CArray myArray; CPerson person;

myArray->Add( person );

简单映射的用法

简单映射类 CMap 采用四个参数:KEY、ARG_KEY、VALUE 和 ARG_VALUE。与数组类和列表类一样,映射类也可以存储任何数据类型。但映射不像数组和列表那样索引和排序它们存储的数据,而是将键与值相关联:通过指定值的关联键访问存储在映射中的值。KEY 参数指定键的数据类型,该键用于访问存储在映射中的数据。如果 KEY 的类型是结构或类,则 ARG_KEY 参数通常是对 KEY 中指定类型的引用。如果 ARG_VALUE VALUE 参数指定存储在映射中的项类型。的类型是结构或类,则 ARG_VALUE 参数通常是对 VALUE 中指定类型的引用。例如: 复制代码

CMap< int, int, MY_STRUCT, MY_STRUCT& > myMap1; CMap< CString, LPCSTR, CPerson, CPerson& > myMap2;

第一个示例存储 MY_STRUCT 值,通过 int 键访问这些值,并通过引用返回访问的 MY_STRUCT 项。第二个示例存储 CPerson 值,通过 CString 键访问这些值,并返回对访问项的引用。该示例可以表示简单的通讯簿,可按姓氏在其中查找人员。

因为 KEY 参数的类型是 CString 且 KEY_TYPE 参数的类型是 LPCSTR,所以键作为 CString 类型的项存储在映射中,但通过 LPCSTR 类型的指针在 SetAt 等函数中被引用。例如: 复制代码

CMap< CString, LPCSTR, CPerson, CPerson& > myMap2; CPerson person;

LPCSTR lpstrName = \myMap2->SetAt( lpstrName, person );

使用类型指针集合模板

若要使用类型指针集合模板,需要知道可以在这些集合中存储的数据类型以及集合声明中所使用的参数类型。

类型指针数组和列表的用法

类型指针数组类 CTypedPtrArray 和列表类 CTypedPtrList 采用两个参数:BASE_CLASS 和 TYPE。这些类可以存储任何在 TYPE 参数中指定的数据类型。它们从存储指针的某个非模板集合类中派生,在 BASE_CLASS 中指定该基类。对于数组,使用 CObArray 或 CPtrArray。对于列表,使用 CObList 或 CPtrList。

实际上,当基于某个类(比如 CObList)声明集合时,新类不仅继承其基类的成员,还声明若干其他的类型安全成员函数和运算符,这些函数和运算符通过封装对基类成员的调用来提供类型安全。这些封装管理所有必需的类型转换。例如: 复制代码

CTypedPtrArray myArray; CTypedPtrList myList;

第一个示例声明了从 CObArray 派生的类型指针数组 myArray。该数组存储并返回指向 CPerson 对象(其中 CPerson 是从 CObject 派生的类)的指针。可以调用任何 CObArray 成员函数,或者可以调用新的类型安全函数 GetAt 和 ElementAt 或使用类型安全运算符 [ ]。

第二个示例声明了从 CPtrList 派生的类型指针列表 myList。该列表存储并返回指向 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 中的 KEY:指定用于查找的键的类型。VALUE 类似于 CMap 中的 VALUE:指定存储在映射中的对象类型。例如: 复制代码

CTypedPtrMap myPtrMap; CTypedPtrMap myObjectMap;

第一个示例是基于 CMapPtrToPtr 的映射,它使用映射到指向 MY_STRUCT 的指针的 CString 键。可通过调用类型安全的 Lookup 成员函数来查找存储的指针。可以使用 [ ] 运算符查找存储的指针;如果没有找到,则添加它。并且可以使用类型安全的 GetNextAssoc 函数迭代映射。也可以调用 CMapPtrToPtr 类的其他成员函数。

第二个示例是基于 CMapStringToOb 的映射,它使用映射到指向 CMyObject 对象的存储指针的字符串键。可以使用在前面的段落中描述的同一类型安全成员,或调用 CMapStringToOb 类的成员。

注意 如果为 VALUE 参数指定 class 或 struct 类型,而不是指定指向该类型的指针或对该类型的引用,则类或结构必须具有复制构造函数。 有关更多信息,请参见如何创建类型安全集合。

CObject类的特性

下面,对三种特性分别描述,并说明程序员在派生类中支持这些特性的方法。

1. 对运行时类信息的支持

该特性用于在运行时确定一个对象是否属于一特定类(是该类的实例),或者从一个特定类派生来的。 CObject提供IsKindOf函数来实现这个功能。

从 CObject派生的类要具有这样的特性,需要:

定义该类时,在类说明中使用 DECLARE_DYNAMIC(CLASSNMAE)宏;

? 在类的实现文件中使用 IMPLEMENT_DYNAMIC(CLASSNAME,BASECLASS)宏。

?

1. 对动态创建的支持

前面提到了动态创建的概念,就是运行时创建指定类的实例。在MFC中大量使用,如前所述框架窗口对象、视对象,还有文档对象都需要由文档模板类(CDocTemplate)对象来动态的创建。 从CObject派生的类要具有动态创建的功能,需要:

定义该类时,在类说明中使用DECLARE_DYNCREATE(CLASSNMAE)宏; ? 定义一个不带参数的构造函数(默认构造函数);

? 在类的实现文件中使用IMPLEMENT_DYNCREATE(CLASSNAME,BASECLASS)宏;

?


学习模板和集合类的建议.doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:江苏科技大学成人 毕业论文要求

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: