CMap成员变量和成员函数难点详细解释

 

本文主要是针对CMap中的成员变量:

 CAssoc** m_pHashTable;
 UINT m_nHashTableSize;
 int m_nCount;
 CAssoc* m_pFreeList;
 struct CPlex* m_pBlocks;
 int m_nBlockSize;

进行解释,以及如何存放。

 

还有就是对成员函数:

 CAssoc* NewAssoc();
 void FreeAssoc(CAssoc*);

 VALUE& operator[](ARG_KEY key);

的实现进行说明。

 

先看看MFC CMap类路径:

C:/Program Files/Microsoft Visual Studio/VC98/MFC/Include/AFXTEMPL.H

部分源码:

 

1.当把元素插入到哈希表中的时候,调用SetAt(ARG_KEY key, ARG_VALUE newValue),然后重载运算符[],来到:

 

pAssoc = NewAssoc()调用后,来到关键的一句:

if (m_pFreeList == NULL)的判断,m_pFreeList 成员变量,在初始化的时候是为空,在分析它之前,先解释一下那3个成员变量:

// m_pFreeList后面再作解释

 CAssoc* m_pFreeList;

// 每一个m_pBlocks就是在内存中m_nBlockSize = 10个用来存放数据的内存结构,相当于一个盒子,可以装下10个插入的数据
 struct CPlex* m_pBlocks;
 int m_nBlockSize;

首先说一下struct CPlex:

Plex,在中文意思是丛,簇的意思,

它只有一个成员变量指针:CPlex* pNext,

 

在每次调用Create函数后,内存中就会分配m_nBlockSize =10(10为nBlockSize在构造函数中默认分配的大小)个单位的空间大小,每一个m_nBlockSize的大小是cbElement,再加上存放结构CPlex的大小,一共是:

sizeof(CPlex) + nMax * cbElement;

因此,每次一个Create后,内存就会分配10个位置的空间用来存放将要插入的数据,也就是一个“丛”,在插入完10个数据后,也就是第一个“丛”已经装满了,这时,又新建一个“丛”,这时候,第一个“丛”的指针CPlex* pNext就会指向下一个“丛”,从而可以实现每一次动态地分配10个单位数据,用来存放插入的数据(但是这时数据还没有插入,只是开辟一片空间,准备用来存放数据),也就是一个“丛”,这些“丛”都组成又一个链表。

 

好,这时候就可以说说m_pFreeList,在新建一个“丛”,也就是调用Create后,

CMap::CAssoc* pAssoc = (CMap::CAssoc*) newBlock->data();

新建一个CAssoc对象pAssoc (也就是要插入的那个元素),放到刚刚新建好的那个“丛”的第一个位置去(每个“丛”有m_nBlockSize =10个位置嘛,前面说了),newBlock->data() 是返回this+1,为什么是+1?因为this是CPlex对象中存放pNext指针的位置,指针后面就是10个单位,+1后就指向了10个单位的第一个位置。

 

这时候,

pAssoc += m_nBlockSize - 1;

把刚刚新建的CAssoc对象移动到“丛”的最后一个位后,这时候m_pFreeList从后面指回到第一个位置上。

如图:

0______      ->“丛”的第一个位置存放指针

1______      ->“丛”的第二个开始存放数据1,m_pFreeList指向这里

2______     m_pFreeList

3______       |

4______       V

5______       会

6______       向

7______       下

8______       移

9______       动

10______     

着数据的插入,m_pFreeList会一直向下移动,

在第一个“丛”放满数据后,m_pFreeList会变成NULL,这时候再新建一个“丛”,第一个“丛的指针pNext指向下一个“丛”:

0______      ->“丛”的第一个位置存放指针

1______      ->“丛”的第二个开始存放数据1,m_pFreeList指向这里

2______     

3______     

4______     

5______     

6______     

7______     

8______     

9______     

10______    

这就是数据在插入和存放的过程.

 

2.在调用FreeAssoc(CMap::CAssoc* pAssoc)进行删除一个数据后,m_pFreeList会指向删除的位置,面删除的位置会指向m_pFreeList原来的位置,这样一来,在删除数据后,所留下的空间会在以后插入数据的时候填充掉,这样可以有效地防止空间的浪费。

 pAssoc->pNext = m_pFreeList;
 m_pFreeList = pAssoc;

 

至于数据的Map中的结构,这就不多说了,也就是一个哈希表的结构!

 

花了2小时,终于完成,小弟第一次100%原创发表,里面可以有很多不足之处,希望大家多多指点!!也希望大家多多支持,学习学习!!!

转帖请注明:n70joey原创于csdn.net!!!!

2010-03-23

 

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值