【vc++精品源码栏目提醒】:文章导读:在新的一年中,各位网友都进入紧张的学习或是工作阶段。
网学会员整理了vc++精品源码-[VC]深入分析MFC中的CArray类 - 采矿施工的相关内容供大家参考,祝大家在新的一年里工作和学习顺利!
我们在使用vc进行比较复杂的编程时,经常需要用到复杂的数组结构,并希望能实现动态管理。
由于C并不支持动态数组,MFC提供了一个CArray类来实现动态数组的功能。
有效的使用CArray类,可以提高程序的效率。
MFC提供了一套模板库,来实现一些比较常见的数据结构如ArrayListMap。
CArray即为其中的一个,用来实现动态数组的功能。
CArray是从CObject派生有两个模板参数,第一个参数就是CArray类数组元素的变量类型,后一个是函数调用时的参数类型。
我们有一个类 class Object,我们要定义一个Object的动态数组,那么我们可以用以下两种方法:CArray Var1CArray Var2Var1与Var2哪一个的效率要高呢? Var2的效率要高。
为什么呢?接下来我们对CArray的源代码做一个剖析就清楚了。
先了解一下CArray中的成员变量及作用。
TYPE m_pData // 数据保存地址的指针int m_nSize // 用户当前定义的数组的大小int m_nMaxSize // 当前实际分配的数组的大小int m_nGrowBy // 分配内存时增长的元素个数首先来看它的构造函数对成员变量进行了初始化。
CArray::CArray m_pData NULL m_nSize m_nMaxSize m_nGrowBy 0SetSize成员函数是用来为数组分配空间的,从这里着手,看CArray是如何对数据进行管理的。
SetSize的函数定义如下:void SetSize int nNewSize int nGrowBy -1 nNewSize 指定数组的大小nGrowBy 如果需要增加数组大小时增加的元素的个数。
对SetSize的代码,进行分析。
由于代码太长,只列出部分重要部分void CArray::SetSizeint nNewSize int nGrowBy if nNewSize 0 // 第一种情况 // 当nNewSize为0时需要将数组置为空 // 如果数组本身即为空则不需做任何处理 // 如果数组本身已含有数据则需要清除数组元素 if m_pData NULL //DestructElements 函数实现了对数组元素析构函数的调用 //不能使用delete m_pData 因为我们必须要调用数组元素的析构函数 DestructElementsm_pData m_nSize //现在才能释放内存 delete BYTEm_pData m_pData NULL m_nSize m_nMaxSize 0 else if m_pData NULL // 第二种情况 // 当m_pDataNULL时还没有为数组分配内存 //首先我们要为数组分配内存,sizeofTYPE可以得到数组元素所需的字节数 //使用new 数组分配了内存。
注意,没有调用构造函数 m_pData TYPE new BYTEnNewSize sizeofTYPE //下面的函数调用数组元素的构造函数 ConstructElementsm_pData nNewSize //记录下当前数组元素的个数 m_nSize m_nMaxSize nNewSizeelse if nNewSize m_nSize // 需要增加元素的情况 // 与第二种情况的处理过程,既然元素空间已经分配, // 只要调用新增元素的构造函数就Ok ConstructElementsm_pDatam_nSize nNewSize-m_nSize else if m_nSize nNewSize // 现在是元素减少的情况,我们是否要重新分配内存呢 // No这种做法不好,后面来讨论。
// 下面代码释放多余的元素不是释放内存,只是调用析构函数 DestructElementsm_pDatanNewSize m_nSize-nNewSize m_nSize nNewSizeelse //这是最糟糕的情况,因为需要的元素大于m_nMaxSize, // 意味着需要重新分配内存才能解决问题 // 计算需要分配的数组元素的个数 int nNewMax if nNewSize m_nMaxSize nGrowBy nNewMax m_nMaxSize nGrowBy else nNewMax nNewSize // 重新分配一块内存 TYPE pNewData TYPE new BYTEnNewMax sizeofTYPE //实现将已有的数据复制到新的的内存空间 memcpypNewData m_pData m_nSize sizeofTYPE // 对新增的元素调用构造函数 ConstructElementspNewDatam_nSize nNewSize-m_nSize //释放内存 delete BYTEm_pData //将数据保存 m_pData pNewData m_nSize nNewSize m_nMaxSize nNewMax 注意上面代码中标注为粗体的代码,它们实现了对象的构造与析构。
如果我们只为对象分配内存,却没有调用构造与析构函数,会