好文档就是一把金锄头!
欢迎来到金锄头文库![会员中心]
电子文档交易市场
安卓APP | ios版本
电子文档交易市场
安卓APP | ios版本

第5章MFC集合类.doc

17页
  • 卖家[上传人]:工****
  • 文档编号:538586051
  • 上传时间:2023-04-07
  • 文档格式:DOC
  • 文档大小:251KB
  • / 17 举报 版权申诉 马上下载
  • 文本预览
  • 下载提示
  • 常见问题
    • 第5章MFC集合类许多C++程序员都使用标准模板库(STL),因为用它很容易实现数组、链接列表、映射 以及其他容器STL语言中“容器”指的是保存数据集合的对象但是在有STL之前,已经有MFC 了在称为“MFC集合类”的一系列类中,MFC提供了自己的数组、链接列表以及映射的实现途径虽然在MFC应用桎序中使用STL类非常安全,但许多MFC程序员还是更喜欢用MFC的集合类,一方面原因是他们更熟悉MFC,另一方面原因是不愿意链接两个独立的类库而增加应用程序的EXE的尺寸有MFC集合类的帮助,您根本不必从头编写一个链接列表本章将介绍MFC集合类并深入说明它们的使用和操作5.1数组C和C++的一个最大缺陷是数组不进行边界检查看一下下面的代码,它反映了C和 C++应用程序中最常见的一种错误:int array[10];for (int i=0; i<=10; i++) array[i] = i + 1;此代码出错是由于for循环中的最后一次迭代赋值超出了数组的范围在运行时会产生非法存取错误 ,C++程序员经常通过编写数组类并在内部进行边界检查来解决此问题下面给出的数组类具有Get和Set函数,用来检查传递给它们的下标,如果传递来的下标无效就进行断言处理:class CArray{protected: int m_nSize; // Number of elements in the array. int* m_pData; // Where the array's elements are stored.public: CArray (int nSize) { m_nSize = nSize; m_pData = new int[nSize]; } ~CArray () { m_nSize = 0; if (m_pData != NULL) { delete[] m_pData; m_pData = NULL; } } int Get (int nIndex) { assert (nIndex >= 0 && nIndex < m_nSize); return m_pData[nIndex]; } void Set (int nIndex, int nVal) { assert (nIndex >= 0 && nIndex < m_nSize); m_pData[nIndex] = nVal; }};用这个简单的类作为整型数组的容器,下列代码在最后一次调用Set时产生断言提示:CArray array (10);for (int i=0; i<=10; i++) array.Set (i, i + 1); // Asserts when i == 10.这样就会避免非法存取错误的发生。

      5.1.1 MFC数组类您不必亲自编写数组类,MFC巳经提供了各种各样的数组首先是一般的CArray类 它实际上是一个模板类,利用它可以创建任何数据类项的类型安全数组在头文件Afxlexn pl.h中定义了CArray其次是非模板化的数组类,分别为保存特定类型的数据而设计这些类在Afxcoll.h中定义表5-1中列出了非模板化的MFC数组类以及它们所保伴的数据类型表5-1 恒定类型的MFC数组类类名数据类型CByleArray8位字节(BYTE)CWordArray16位字节(WORD)CDWoKlArray32位双字(DWORD)CUInl Array无符号整型(UINT)CStringArrayCStringCPlrAmyvoid指针CObArrayCObject 指针 只要学会使用这些数组类中的一种,也就学会使用其他数组类,因为它们共享公用的一组成员函数下例声明了一个包含10个UINT的数组并用数字1到10对它进行了初 始化:CUIntArray array;array.SetSize (10);for (int i=0; i<10; i++) array[i] = i + 1;可以采用相同的方法来声明一个CStrings数组并用整数I到10的文本表示来初始化它:CStringArray array;array.SetSize (10);for (int i=0; i<10; i++) { CString string; string.Format (_T ("%d"), i); array[i] = string;} 在两个例子中,都是用SetSize来指定数组包含10个元素;重载“[]"运算符调用数组的SetAt 函数,该函数将值复制到数组中指定位置处的元素中;如果数组边界非法,程序将执行断言 处理。

      边界检査内置在SetAt代码中:ASSERT(nIndex >= 0 && nIndex < m_nSize); 在MFC源程序文件Afxcoll.inl中您可以看到此代码可以使用InsertAt函数在不覆盖已有数组项的情况下给数组插入元素项与SetAt不 同,它只是给已存在的数组元素赋值,lnSertAt还要给新的元素分配空间,通过把数组中插入点上方的元素向上移动来完成下列语句用数字1到4和6到10初始化一个数组并在数字4和6之间插入5:CUIntArray array;array.SetSize (9);for (int i=0; i<4; i++) array[i] = i + 1;for (i=4; i<9; i++) array[i] = i + 2;array.InsertAt (4, 5); // Insert a 5 at index 4. 还可以给InsertAt传递第三个参数指定元素项被插入的次数,或是在第二个参数中传递指向另一个数组对象的指针来插入整个数组注意在本例中数组的大小为9个元素而不是10个,而在调用InsertAt时却没有执行断言处理。

      这是因为lnsertAt是那些便于使用的函数之一,它们在新的元素项添加到数组中时自动增大数组尺寸动态调整数组大小将在下一节讨论 使用标准数组寻址语法可以在MFC数组中检索所要的值,下例将读取先前例子中写入 CUInlArray 中的 UINT:for (int i=0; i<10; i++) UINT nVal = array[i]; 使用此方法,[]运算符将调用数组的函数,该函数从数组中的指定位置取回一个值(当然要进行边界检査)如果愿意您可以直接调用GetAt而不用通过[]运算符 要确定数组包含元素的个数,可以调用数组的GetSize函数还可以调用GetUpperBound返回数组的上界下标,因为下标从0开始,所以其值为数组元素总数减1MFC的数组类为从数组中删除元素提供了两个函数:RemoveAt和RemoveAllRemoveAt 从数组中删除一个以上的元素项并将被删除元素项上边的所有元素项向下移动RemoveAll清空整个数组两个函数都将调整数组的上界从而反映出被删除的元素项个数. 说明如下:// Add 10 items.CUIntArray array;array.SetSize (10);for (int i=0; i<10; i++) array[i] = i + 1;// Remove the item at index 0.array.RemoveAt (0);TRACE (_T ("Count = %d\n"), array.GetSize ()); // 9 left.// Remove items 0, 1, and 2.array.RemoveAt (0, 3);TRACE (_T ("Count = %d\n"), array.GetSize ()); // 6 left.// Empty the array.array.RemoveAll ();TRACE (_T ("Count = %d\n"), array.GetSize ()); // 0 left. Remove函数删除元素,但是如果元素是指针时它并不删除指针所指的对象。

      如果数组是 CPtrArray或CObArray类型的,要清空数组并删除被删除指针所指的对象,就不应该写成:array.RemoveAll ();要写成:int nSize = array.GetSize ();for (int i=0; i

      因此,在调用SetSize之后只有新项需要明确的初始化 另一种增大数组的方法是调用SetAtGrow而不是SetAt来添加元素项例如:下列代码试图用SetAt给UINT数组添加10个元素项:CUIntArray array;for (int i=0; i<10; i++) array.SetAt (i, i + 1); 此程序会在第一次调用SetAt时就执行断言处理为什么?因为数组大小为零时(注意没有调 用SetSize) 不会自动增大数组来容纳新的元素但是,将SetAt更改为SetAtGrow后,程序将顺利执行:CUIntArray array;for (int i=0; i<10; i++) array.SetAtGrow (i, i + 1); 与SetAt不同,SetAtGrow会在必要时自动增大数组的内存分配空间Add函数也是这样,它将元素项添加到数组的末尾下一个例子的功能与上一个的相同,只是使用了Add而不是 SetAtGrow来给数组添加元素:CUIntArray array;for (int i=0; i<10; i++)array.Add (i + 1);其他可以自动增。

      点击阅读更多内容
      关于金锄头网 - 版权申诉 - 免责声明 - 诚邀英才 - 联系我们
      手机版 | 川公网安备 51140202000112号 | 经营许可证(蜀ICP备13022795号)
      ©2008-2016 by Sichuan Goldhoe Inc. All Rights Reserved.